从本地文件动态加载程序集并以受限制的权限运行

时间:2016-01-28 12:05:40

标签: c# security reflection .net-assembly appdomain

我需要做的是:阅读本地C#文本文件,从中执行一个方法。这就是我正在做的事情。

  1. 阅读文件中的所有文字
  2. 使用x.dll
  3. 编译为本地CSharpCodeProvider
  4. 使用Assembly.LoadFrom()
  5. 加载dll
  6. 然后使用GetType().GetMethod().Invoke()
  7. 执行方法

    工作正常。现在,我想安全地运行此代码,即限制此代码访问文件系统,网络等。基本上,我需要以最小的权限运行它。

    我尝试了来自Restrict plugin access to file system and network via appdomain的代码(由@Babar回答),但仍未按预期工作。文本文件中的代码仍然可以访问文件系统。

    我在这里缺少什么?还有其他任何方法可以使它发挥作用吗?

    代码(用于加载和执行程序集)

    public class Sandboxer
    {
        public static T GetResult<T>(string untrustedAssemblyDirectory, string assemblyFullPath, string className, string methodName, object[] methodParameters)
        {
            AppDomainSetup adSetup = new AppDomainSetup();
            adSetup.ApplicationBase = Path.GetFullPath(untrustedAssemblyDirectory);
    
            PermissionSet permSet = new PermissionSet(PermissionState.None);
            permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
    
            StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();
    
            AppDomain newDomain = AppDomain.CreateDomain("Sandboxer", null, adSetup, permSet, fullTrustAssembly);
    
            ObjectHandle handle = Activator.CreateInstanceFrom(
                newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
                typeof(Sandboxer).FullName
                );
    
            Sandboxer newDomainInstance = (Sandboxer)handle.Unwrap();
            return newDomainInstance.ExecuteUntrustedCode<T>(assemblyFullPath, className, methodName, methodParameters);
        }
    
        public T ExecuteUntrustedCode<T>(string assemblyName, string typeName, string entryPoint, Object[] parameters)
        {
            var method = Assembly.LoadFrom(assemblyName).GetType(typeName).GetMethod(entryPoint);
            try
            {
                T retVal = (T)method.Invoke(null, parameters);
                return retVal;
            }
            catch (Exception ex)
            {
                var expMsg = string.Empty;
                (new PermissionSet(PermissionState.Unrestricted)).Assert();
                expMsg = "Exception :\n{0}" + ex.ToString();
                CodeAccessPermission.RevertAssert();
                throw new ApplicationException(expMsg);
            }
        }
    }
    

0 个答案:

没有答案