反映不受限制,即使它不在授权集中

时间:2012-02-09 19:57:43

标签: c# .net security .net-4.0 sandbox

我目前正在尝试创建一个非常简单的沙箱

某个类 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();
        }
    }
}

3 个答案:

答案 0 :(得分:11)

调用无法访问的成员时需要反映权限。 AB是具有公共构造函数的公共类型,因此可以访问。您可以在没有反射的情况下调用那些构造函数,因此当您尝试使用反射时,没有要求。

此外,使用发现的反射总是合法的;即使没有获得反射许可,您也可以查询对象并询问其私有成员列表。只有当您尝试对私有成员进行调用时才需要该权限。

答案 1 :(得分:2)

来自MSDN LibraryReflectionPermission通过System.Reflection API控制对非公开类型和成员的访问。如果没有ReflectionPermission,代码可以使用反射来仅访问对象的公共成员。

答案 2 :(得分:1)

你在.net 3.5上检查了你的代码吗? .NET 4有一个新的 安全模型,其中授权集不再影响sansbox。当我想在完全信任的.net进程上测试打算在中等信任上下文中运行的代码时,我被此严重咬了。

一种可能的解决方案是强制CLR使用旧版安全模型,然后在新AppDomain中明确拒绝ReflectionPermission。

对不起部分答复,我现在正在使用手机,但明天会回来查看。希望这能让你开始。