执行不受信任的代码
Posted
技术标签:
【中文标题】执行不受信任的代码【英文标题】:Executing untrusted code 【发布时间】:2010-03-13 12:51:41 【问题描述】:我正在构建一个使用插件的 C# 应用程序。应用程序必须向用户保证插件不会在用户机器上为所欲为,并且具有比应用程序本身更少的权限(例如,应用程序可以访问自己的日志文件,而插件不能) .
我考虑了三种选择。
使用 System.AddIn。我首先尝试了这个替代方案,因为它非常强大,但是每次我想要修改某些东西时,我都需要在七个不同的项目中修改七次相同的代码,这让我感到非常失望。此外,即使是一个简单的 Hello World 应用程序,也有大量的问题需要解决。
使用 System.Activator.CreateInstance(assemblyName, typeName)。这是我在之前版本的应用程序中使用的。我再也不能使用它了,因为它没有提供限制权限的方法。
使用 System.Activator.CreateInstance(AppDomain 域,[...])。这就是我现在要实现的,但似乎唯一的方法是通过 ObjectHandle,这需要对每个使用的类进行序列化。虽然插件包含 WPF 用户控件,但它们是不可序列化的。
那么有没有办法创建包含 UserControl 或其他不可序列化对象的插件并使用自定义 PermissionSet 执行这些插件?
【问题讨论】:
【参考方案1】:您可以做的一件事是将当前 AppDomain 的策略级别设置为受限权限集,并添加证据标记以根据强名称或位置进行限制。最简单的可能是要求插件位于特定目录中并为它们提供限制性策略。
例如
public static void SetRestrictedLevel(Uri path)
PolicyLevel appDomainLevel = PolicyLevel.CreateAppDomainLevel();
// Create simple root policy normally with FullTrust
PolicyStatement fullPolicy = new PolicyStatement(appDomainLevel.GetNamedPermissionSet("FullTrust"));
UnionCodeGroup policyRoot = new UnionCodeGroup(new AllMembershipCondition(), fullPolicy);
// Build restrictred permission set
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
PolicyStatement permissions = new PolicyStatement(permSet, PolicyStatementAttribute.Exclusive);
policyRoot.AddChild(new UnionCodeGroup(new UrlMembershipCondition(path.ToString()), permissions));
appDomainLevel.RootCodeGroup = policyRoot;
AppDomain.CurrentDomain.SetAppDomainPolicy(appDomainLevel);
static void RunPlugin()
try
SetRestrictedLevel(new Uri("file:///c:/plugins/*"));
Assembly a = Assembly.LoadFrom("file:///c:/plugins/ClassLibrary.dll");
Type t = a.GetType("ClassLibrary.TestClass");
/* Will throw an exception */
t.InvokeMember("DoSomething", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null, null, null);
catch (Exception e)
Console.WriteLine(e.ToString());
当然,这并没有经过严格测试,而且 CAS 政策非常复杂,因此始终存在此代码可能允许某些事情绕过政策的风险,YMMV :)
【讨论】:
以上是关于执行不受信任的代码的主要内容,如果未能解决你的问题,请参考以下文章
当执行太多不受信任的代码时,除去令人讨厌的大量 trycatch 的办法