Bouke
Bouke

Reputation: 12138

Create AppDomain without/empty CallContext

Inside an ASP.NET application, I want to create an AppDomain in which untrusted code will be running. However when initializing and unwrapping my assembly loader, an exception is thrown about a type that I'm not passing in. It's the current user from the web request (HttpContext.Current.User), which I think is made available through LocalCallContext. I don't want the current user to be available to the untrusted code, in fact I want the untrusted code to get NO context at all. So I imagine I would be able to pass in an explicit CallContext, but there doesn't appear to be such a thing. How would I achieve this?

The untrusted code are user-provided Razor templates, which will be executed through RazorEngine.

Evidence evidence = new Evidence();
evidence.AddHostEvidence(new Zone(SecurityZone.Internet));
PermissionSet permissionSet = SecurityManager.GetStandardSandbox(evidence);
FileIOPermission permission = new FileIOPermission(PermissionState.None);
FileIOPermissionAccess access = FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery;
permission.AddPathList(access, typeof(AssemblyLoader).Assembly.Location);
permissionSet.AddPermission(permission);

// We have to load ourself with full trust
StrongName loaderAssembly = typeof(AssemblyLoader).Assembly.Evidence.GetHostEvidence<StrongName>();
StrongName razorEngineAssembly = typeof(RazorEngineService).Assembly.Evidence.GetHostEvidence<StrongName>();
StrongName razorAssembly = typeof(RazorTemplateEngine).Assembly.Evidence.GetHostEvidence<StrongName>();
AppDomainSetup appDomainSetup = new AppDomainSetup
{
    ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
};
AppDomain sandBoxDomain = AppDomain.CreateDomain("Razor Template Sandbox", null, appDomainSetup, permissionSet, loaderAssembly, razorEngineAssembly, razorAssembly);

AssemblyLoader loader = (AssemblyLoader)sandBoxDomain.CreateInstanceFromAndUnwrap(typeof(AssemblyLoader).Assembly.Location, typeof(AssemblyLoader).FullName);

The last line throws this exception, UnrelatedAssembly.SomeType being the type of my HttpContext.Current.User:

System.Runtime.Serialization.SerializationException: 'Type is not resolved for member 'UnrelatedAssembly.SomeType,UnrelatedAssembly, Version=1.9.0.0, Culture=neutral, PublicKeyToken=null'.'

Upvotes: 0

Views: 217

Answers (1)

Bouke
Bouke

Reputation: 12138

I resolved parts of this issue by suppressing flow of the execution context, and running all code in the target app domain from a separate thread. This looks like this:

var flow = ExecutionContext.SuppressFlow();
try
{
    return Task.Factory.StartNew(() =>
    {
        Thread.CurrentPrincipal = null;
        // setup app domain / run code in other app domain here
        return ....;
    }).Result;
}
finally
{
    flow.Undo();
}

Upvotes: 0

Related Questions