Отражение не ограничено, даже если оно не входит в набор разрешений

Сейчас я пытаюсь создать очень-очень простую песочницу .

У некоторого класса 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();
        }
    }
}
5
задан Matías Fidemraizer 10 February 2012 в 15:27
поделиться