即使不在拨款集中,反射也不受限制

发布于 2025-01-04 07:10:33 字数 2785 浏览 2 评论 0原文

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

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

更新

太棒了!终于我做到了。

感谢您的建议,我修改了我的代码,我想与您分享,因为我很难理解如何不使用 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();
        }
    }
}

I'm currently trying to create a very very simple sandbox.

Some class A has a method Execute which is invoked in another AppDomain than the caller.

Problem is I've execution permission only and reflection is possible anyway.

This is the code sample:

[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();
    }
}

UPDATE

Great! Finally I did it.

Thanks to your advices I've revised my code and I'd like to share it with you, since I had a hard time understanding how to don't use CAS but use same kind of permissions in the new .NET 4.x and above security model, and the way of sandboxing using an AppDomain. That's it:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦萦几度 2025-01-11 07:10:33

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

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

Reflection permission is demanded when invoking an inaccessible member. A and B are public types with public constructors, and so are accessible. You could invoke those constructors without reflection, so there is no demand when you attempt to do so with reflection.

Moreover, using reflection for discovery is always legal; you can interrogate an object and ask it for a list of its private members, even without reflection permission being granted. It is only when you attempt to cause an invocation of the private member that the permission is demanded.

深海少女心 2025-01-11 07:10:33

From MSDN Library: ReflectionPermission controls access to non-public types and members through the System.Reflection APIs. Without ReflectionPermission, code can use reflection to access only the public members of objects.

虫児飞 2025-01-11 07:10:33

您检查过 .net 3.5 上的代码吗? .NET 4 有一个新的
授予集不再影响 sansbox 的安全模型。当我想要测试打算在完全信任的 .net 进程上的中等信任上下文中运行的代码时,我对此深感困扰。

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

抱歉回答不完整,我现在正在使用移动设备,但明天会再回来查看。希望这能让你开始。

Have you checked your code on .net 3.5? .NET 4 has a new
security model where the grant sets do no longer affect the sansbox. I was seriously bitten by this when I wanted to test code intended to run in medium trust contexts on a full trust .net process.

A possible solution is to force the CLR to use the legacy security model and then explicitly deny ReflectionPermission in the new AppDomain.

Sorry for the partial answer, I'm on mobile right now but will check back tomorrow. Hope this gets you started.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文