通过appdomain限制对文件系统和网络的插件访问

我刚才问过如何限制插件访问(我想阻止他们写入磁盘或网络),我被告知要使用AppDomain 。 我已经搜索并尝试过如何使其工作失败。

任何人都可以提供一些信息,这样我就可以开始了,只需制作一个不允许写入文件或网络的AppDomain。

如果我理解你的观点,我想这就是你所需要的。

System.Security.PermissionSet ps = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None); ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.NoAccess, "C:\\")); System.Security.Policy.PolicyLevel pl = System.Security.Policy.PolicyLevel.CreateAppDomainLevel(); pl.RootCodeGroup.PolicyStatement = new System.Security.Policy.PolicyStatement(ps); AppDomain.CurrentDomain.SetAppDomainPolicy(pl); System.Reflection.Assembly myPluginAssembly = AppDomain.CurrentDomain.Load("MyPluginAssembly"); 

这更准确地说是你的意思吗?

请注意,您可以提供一个字符串数组,其中包含您不希望插件具有访问权限的路径。 您可以在初始化FileIOPermission类的新实例时提供。

如果这有帮助,请告诉我。 🙂

对于.net framework 4.0,请按照此 MSDN文章中的以下代码进行操作。

以下示例实现上一节中的过程。 在该示例中,Visual Studio解决方案中名为Sandboxer的项目还包含名为UntrustedCode的项目,该项目实现了UntrustedClass类。 此方案假定您已下载包含预期返回true或false的方法的库程序集,以指示您提供的数字是否为Fibonacci数。 相反,该方法尝试从您的计算机中读取文件。 以下示例显示了不受信任的代码。

 using System; using System.IO; namespace UntrustedCode { public class UntrustedClass { // Pretend to be a method checking if a number is a Fibonacci // but which actually attempts to read a file. public static bool IsFibonacci(int number) { File.ReadAllText("C:\\Temp\\file.txt"); return false; } } } 

以下示例显示了执行不受信任代码的Sandboxer应用程序代码。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Security; using System.Security.Policy; using System.Security.Permissions; using System.Reflection; using System.Runtime.Remoting; //The Sandboxer class needs to derive from MarshalByRefObject so that we can create it in another // AppDomain and refer to it from the default AppDomain. class Sandboxer : MarshalByRefObject { const string pathToUntrusted = @"..\..\..\UntrustedCode\bin\Debug"; const string untrustedAssembly = "UntrustedCode"; const string untrustedClass = "UntrustedCode.UntrustedClass"; const string entryPoint = "IsFibonacci"; private static Object[] parameters = { 45 }; static void Main() { //Setting the AppDomainSetup. It is very important to set the ApplicationBase to a folder //other than the one in which the sandboxer resides. AppDomainSetup adSetup = new AppDomainSetup(); adSetup.ApplicationBase = Path.GetFullPath(pathToUntrusted); //Setting the permissions for the AppDomain. We give the permission to execute and to //read/discover the location where the untrusted code is loaded. PermissionSet permSet = new PermissionSet(PermissionState.None); permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); //We want the sandboxer assembly's strong name, so that we can add it to the full trust list. StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence(); //Now we have everything we need to create the AppDomain, so let's create it. AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly); //Use CreateInstanceFrom to load an instance of the Sandboxer class into the //new AppDomain. ObjectHandle handle = Activator.CreateInstanceFrom( newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName, typeof(Sandboxer).FullName ); //Unwrap the new domain instance into a reference in this domain and use it to execute the //untrusted code. Sandboxer newDomainInstance = (Sandboxer) handle.Unwrap(); newDomainInstance.ExecuteUntrustedCode(untrustedAssembly, untrustedClass, entryPoint, parameters); } public void ExecuteUntrustedCode(string assemblyName, string typeName, string entryPoint, Object[] parameters) { //Load the MethodInfo for a method in the new Assembly. This might be a method you know, or //you can use Assembly.EntryPoint to get to the main function in an executable. MethodInfo target = Assembly.Load(assemblyName).GetType(typeName).GetMethod(entryPoint); try { //Now invoke the method. bool retVal = (bool)target.Invoke(null, parameters); } catch (Exception ex) { // When we print informations from a SecurityException extra information can be printed if we are //calling it with a full-trust stack. (new PermissionSet(PermissionState.Unrestricted)).Assert(); Console.WriteLine("SecurityException caught:\n{0}", ex.ToString()); CodeAccessPermission.RevertAssert(); Console.ReadLine(); } } } 

如果你正在使用插件,你可能也许知道代理。

通过代理加载程序集时,如果我没记错的话,可以通过LoadAssembly()方法为此特定程序集指定安全策略级别。 换句话说,这是通过反思来完成的。

我知道我的答案并不那么详细,但我希望它会让你知道在哪里寻找你的解决方案。 我将密切关注这个问题的进一步细节,以便我可以提供更好的帮助。 =)

希望您在完成后分享您的发现。