none
AppDomain sandbox security exception when subscribing to new domain events RRS feed

  • Question

  • I'm writing a plugin system to run client-provided untrusted code in my server application (C#, .NET 4.0). In order to do this, i'm running each plugin in a new sandboxed AppDomain.

    However, I'm stuck on a security exception that I don't really understand the reason for. I have made a streamlined console application sample to illustrate the problem:

    namespace SandboxTest
    {
        class Program
        {
            static void Main( string[] args )
            {
                Sandbox sandbox = new Sandbox();
                Console.ReadLine();
            }
        }
    
        class Sandbox
        {
            AppDomain domain;
    
            public Sandbox()
            {
                PermissionSet ps = new PermissionSet( PermissionState.None );
                ps.AddPermission( new SecurityPermission( SecurityPermissionFlag.Execution ) );
    
                try
                {
                    domain = AppDomain.CreateDomain( "Sandbox", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation, ps );
                    domain.AssemblyLoad += new AssemblyLoadEventHandler( domain_AssemblyLoad );
                    domain.AssemblyResolve += new ResolveEventHandler( domain_AssemblyResolve );
                }
                catch( Exception e )
                {
                    Trace.WriteLine( e.ToString() );
                    throw e;
                }
            }
    
            static Assembly domain_AssemblyResolve( object sender, ResolveEventArgs args )
            {
                return null;
            }
    
            static void domain_AssemblyLoad( object sender, AssemblyLoadEventArgs args )
            {
    
            }
        }
    }
    

    Upon running this code, I'm getting the following exception on the domain.AssemblyLoad line:

    A first chance exception of type 'System.Security.SecurityException' occurred in SandboxTest.exe
    'SandboxTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
       at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
       at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Object assemblyOrString, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
       at System.Security.CodeAccessSecurityEngine.CheckHelper(PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, Object assemblyOrString, SecurityAction action, Boolean throwException)
       at System.Security.CodeAccessSecurityEngine.CheckHelper(CompressedStack cs, PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action)
       at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
       at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
       at System.Security.CodeAccessPermission.Demand()
       at System.DelegateSerializationHolder.GetDelegateSerializationInfo(SerializationInfo info, Type delegateType, Object target, MethodInfo method, Int32 targetIndex)
       at System.MulticastDelegate.GetObjectData(SerializationInfo info, StreamingContext context)
       at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj, String& typeName, String& assemName, String[]& fieldNames, Object[]& fieldValues)
    
    
       at System.AppDomain.add_AssemblyLoad(AssemblyLoadEventHandler value)
       at SandboxTest.Sandbox..ctor() in C:\Dev\Projects\Botfield\SandboxTest\Program.cs:line 36
    The action that failed was:
    Demand
    The type of the first permission that failed was:
    System.Security.Permissions.ReflectionPermission
    The first permission that failed was:
    <IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    version="1"
    Flags="MemberAccess"/>
    
    The demand was for:
    <IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    version="1"
    Flags="MemberAccess"/>
    
    The granted set of the failing assembly was:
    <PermissionSet class="System.Security.PermissionSet"
    version="1">
    <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    version="1"
    Flags="Execution"/>
    </PermissionSet>
    


    Obviously something's trying to use some reflection operations that are not allowed. I could add a ReflectionPermission to the permission set, but wouldn't that allow untrusted code to circumvent the sandbox by using invokes via reflection? Could you help me get a better understanding of what's going on here, along with suggestions on how to achieve my stated goal?

    Thanks in advance!

    Sunday, October 16, 2011 4:25 PM

Answers