Handling security of dynamically generated code?

  • Thread starter Thread starter =?iso-8859-1?Q?Peter_Str=F8iman?=
  • Start date Start date
?

=?iso-8859-1?Q?Peter_Str=F8iman?=

Hi.

I have an application where I dynamically compile code. The code is stored in a database, and is at runtime compiled to an assembly file. I then load the assembly file and call some methods in this file.

I would like to limit the amount of functionality that these assemblies can access. E.g. I don't want any file system access to be available. The assemblies should however be able to access other assemblies that does have this ability. E.g. I could reference an assembly that writes to a logfile. Thus the dynamically compiled assembly can not directly access the log file, but the referenced assembly can.

Here is a simplified version of the code I use. The class Script is a class that contains the code coming from the database. It specifies a language that I use to determine which code provider to create. And it contains a name that is used to determine the output file name of the generated assembly.

For the assembly to work, it must contain a class that is a subclass of my class ScriptObject. A reference to the assembly that defines this class is passed to the compiler. This is done in order for me to be able to initialise members that are then avaible to the code.

Anybody have any clues to how I can implement code permissions for my generated assembly.
One idea I was thinking about was to sign my generated assembly with a specific key-file, and then adjust the framework configuration to give assemblies signed with this specific key limited permissions. Would that work?

Thanks in advance,
Peter Strøiman

public override object Execute(string EventName, ref object[] Arguments, System.Collections.IDictionary projectVars, System.Collections.IDictionary userVars)
{
Assembly assembly = CompileScript( Script );
foreach( Type type in assembly.GetTypes() )
{
if ( type.IsSubclassOf( typeof( ScriptObject ) ) )
{
MemberInfo[] members = type.GetMember( EventName );
if ( members.Length > 0 )
{
ScriptObject scriptObject = (ScriptObject)type.GetConstructor( Type.EmptyTypes ).Invoke( new object[0] );


// Here I initialise the object.
return type.InvokeMember( EventName, BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.InvokeMethod | BindingFlags.IgnoreCase,
null, scriptObject, Arguments );
}
}
}
return null;
}

public Assembly CompileScript( Script script )
{
string[] references = GetReferences( script, names );
CodeDomProvider codeProvider = CreateDomProvider( script );
ICodeCompiler compiler = codeProvider.CreateCompiler();
string fileName = GetOutputFileName( script );
CompilerParameters cp = new CompilerParameters(
references, fileName, false );
CompilerResults cr = compiler.CompileAssemblyFromSource( cp, script.Code );
if ( cr.Errors.Count > 0 )
{
// Handle compiler error.
}
if ( cr.NativeCompilerReturnValue != 0 )
{
// Handle compiler errors again.
}
return Assembly.LoadFrom( fileName );
}
 
Hi Peter.

I have a related question.

We have written an SMTP event sink using managed code. The event sink
processes incoming messages and for messages in a given format it uses the
contents to populate a database and generate some documents. The documents
are generated using a "template" document which is very similar to ASPX
format and can include code. We read the template and generate a class from
it which is then utilised, in conjunction with the e-mail contents, to
generate the final document. We generate the code using
CompileAssemblyFromSource(...) and we generate the Assembly in memory rather
than creating an output file.

This is working beautifully UNTIL we deploy it into the SMTP environment.
Once we deploy, we don't seem to be able to instantiate the generated
classes. I am certain this is a security issue although the framework isn't
throwing any exceptions, just returning a null reference from the
CreateInstance(...) call.

So my question is, how are the permissions of the generated assemblies
determined? How are they (or can they be) changed on-the-fly?

Phil.
 
Back
Top