Search code examples
c#sandboxcode-access-security

Sandboxing untrusted code in c#, Security Permissions seem not working


This is my code:

System.Security.PermissionSet PS = new System.Security.PermissionSet(PermissionState.None);
PS.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess,Path));
PS.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
AppDomainSetup ADS = new AppDomainSetup();
ADS.ApplicationBase= Path;           
AppDomain domain = AppDomain.CreateDomain("Pluging", null, ADS, PS, null);            
Assembly asm = Assembly.LoadFrom(Path + "MacroBase.dll");
domain.Load(asm.FullName);
MacroBase.MacroBase em = (MacroBase.MacroBase)domain.CreateInstanceAndUnwrap(asm.FullName, "MacroBase.MacroBase");
em.Application(1);

parameter Path has the address of floder that contains dll. Right now it is "D:\Programming Projects\Server3\Macros\c7b465b2-8314-4c7e-be3c-10c0185b4ac6" a copy of macrobase.dll is inside that Guid folder. Appdomain loads this dll and runs the method Application.

I expected the last line not to be able to access c:\ due to FileIOPermissionAccess that was applied at the beginning, but the mentioned method:

MacroBase.Application(int i)
{ 
    System.IO.File.ReadAllBytes("c:\\test1_V.103.xls");
}

runs as if it was fully unrestricted.

based on this article from Microsoft: How to: Run Partially Trusted Code in a Sandbox I have also tried the following format with no better results(It can access c:):

System.Security.PermissionSet PS = new System.Security.PermissionSet(PermissionState.None);
PS.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess,Path));
PS.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
AppDomainSetup ADS = new AppDomainSetup();
ADS.ApplicationBase= Path;           
AppDomain domain = AppDomain.CreateDomain("Pluging", null, ADS, PS, null);            
Assembly asm = Assembly.LoadFrom(Path + "MacroBase.dll");
domain.Load(asm.FullName);
System.Runtime.Remoting.ObjectHandle handle = Activator.CreateInstanceFrom(domain, Path + "MacroBase.dll", "MacroBase.MacroBase");
MacroBase.MacroBase m = (MacroBase.MacroBase)handle.Unwrap();
m.Application(1);

MacroBase.Macrobase is a placeholder for future macros. It is placed inside a dll called macrobase.dll . Right now it only contains some dummy code:

namespace MacroBase
{
    [Serializable]
    public class MacroBase
    {
        public void Application(int i)
        {

            List<int> i1 = new System.Collections.Generic.List<int>() { 1,2,3,4};

            System.IO.File.ReadAllBytes("c:\\test1_V.103.xls");
            switch(i)
            {
                case 0:
                    break;
                case 1:
                    break;
                default:
                    break;
            }
        }
    }
}

Solution

  • Your class marked as [Serializable] and does not derive from MarshalByRefObject, that means when instance get thru Application domain boundaries, it get serialized and than deserialized in target domain. So your code get executed in your current domain rather then in separate domain. You should derive your MacroBase.Macrobase class from MarshalByRefObject, to make code to be executed in separate domain.