即使反射';s不在授权集中

本文关键字:授权 集中 反射 | 更新日期: 2023-09-27 18:24:01

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

某些类A有一个方法Execute,该方法在调用方之外的另一个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();
    }
}

更新

太棒了我终于做到了。

由于您的建议,我修改了我的代码,并希望与您分享,因为我很难理解如何在新的.NET 4.x及更高版本的安全模型中不使用CAS,但使用相同类型的权限,以及使用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();
        }
    }
}

即使反射';s不在授权集中

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

此外,对发现使用反射总是合法的;您可以询问一个对象,并要求它提供其私人成员的列表,即使没有授予反射权限。只有当您试图对私有成员进行调用时,才需要该权限。

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

您在.net 3.5上检查过代码吗。NET 4有一个新grant集不再影响sansbox的安全模型。当我想在完全信任的.net进程上测试在中等信任上下文中运行的代码时,我受到了严重的影响。

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

很抱歉得到部分答复,我现在正在使用手机,但明天会回来查看。希望这能让你开始。