我目前正在尝试创建一个非常简单的沙箱。
某个类 A 有一个方法执行,它在另一个AppDomain
中调用,而不是调用者。
问题是我只有执行权限,无论如何都可以反思。
这是代码示例:
[Serializable]
public class A : MarshalByRefObject
{
public void Execute()
{
typeof(A).GetConstructor(Type.EmptyTypes).Invoke(null); // Fine - Why?
typeof(B).GetConstructor(Type.EmptyTypes).Invoke(null); // Fine - Why?
}
}
public class B
{
}
class Program
{
static void Main(string[] args)
{
PermissionSet set = new PermissionSet(PermissionState.None);
SecurityPermission security = new SecurityPermission(SecurityPermissionFlag.Execution);
set.AddPermission(security);
Evidence evidence = new Evidence();
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = "C:";
AppDomain domain = AppDomain.CreateDomain
(
"hello",
evidence,
setup,
set
);
A a = (A)domain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(A).FullName);
a.Execute();
}
}
更新
太棒了!最后我做到了。
感谢您的建议我修改了我的代码,我想与您分享,因为我很难理解如何不使用CAS但在新版本中使用相同类型的权限.NET 4.x及更高版本的安全模型,以及使用AppDomain
进行沙盒的方式。就是这样:
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
namespace ConsoleApplication1
{
[Serializable]
public class A : MarshalByRefObject
{
public void Execute()
{
B b = new B();
// BOMB! ERROR! Security demand: reflection forbidden!
b.GetType()
.GetMethod("ExecuteInB", BindingFlags.Instance | BindingFlags.NonPublic)
.Invoke(b, null);
}
}
public class B
{
private void ExecuteInB()
{
}
}
class Program
{
static void Main(string[] args)
{
PermissionSet set = new PermissionSet(PermissionState.None);
SecurityPermission security = new SecurityPermission(PermissionState.None);
security.Flags = SecurityPermissionFlag.Execution;
set.AddPermission(security);
Evidence evidence = new Evidence();
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = "C:";
AppDomain domain = AppDomain.CreateDomain
(
"hola",
evidence,
setup,
set
);
A a = (A)domain.CreateInstanceAndUnwrap("ConsoleApplication1", "ConsoleApplication1.A");
a.Execute();
}
}
}
答案 0 :(得分:11)
调用无法访问的成员时需要反映权限。 A
和B
是具有公共构造函数的公共类型,因此可以访问。您可以在没有反射的情况下调用那些构造函数,因此当您尝试使用反射时,没有要求。
此外,使用发现的反射总是合法的;即使没有获得反射许可,您也可以查询对象并询问其私有成员列表。只有当您尝试对私有成员进行调用时才需要该权限。
答案 1 :(得分:2)
来自MSDN Library:ReflectionPermission
通过System.Reflection API控制对非公开类型和成员的访问。如果没有ReflectionPermission
,代码可以使用反射来仅访问对象的公共成员。
答案 2 :(得分:1)
你在.net 3.5上检查了你的代码吗? .NET 4有一个新的 安全模型,其中授权集不再影响sansbox。当我想在完全信任的.net进程上测试打算在中等信任上下文中运行的代码时,我被此严重咬了。
一种可能的解决方案是强制CLR使用旧版安全模型,然后在新AppDomain中明确拒绝ReflectionPermission。
对不起部分答复,我现在正在使用手机,但明天会回来查看。希望这能让你开始。