3

目標: 非常に限られたアクセス許可で AppDomain でいくつかのコードを実行する必要があります。他の場所で定義したいくつかのヘルパー メソッドを除いて、ファンシーまたは安全でないものには一切アクセスできないはずです。

私がやったこと: 必要な基本的なアクセス許可を持つサンドボックス AppDomain を作成し、コードを実行するプロキシ オブジェクトを作成しています。

static AppDomain CreateSandbox()
{
    var e = new Evidence();
    e.AddHostEvidence(new Zone(SecurityZone.Internet));

    var ps = SecurityManager.GetStandardSandbox(e);
    var security = new SecurityPermission(SecurityPermissionFlag.Execution);

    ps.AddPermission(security);

    var setup = new AppDomainSetup { 
        ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) 
    };
    return AppDomain.CreateDomain("Sandbox" + DateTime.Now, null, setup, ps);
}

public class Proxy : MarshalByRefObject
{
    public Proxy() { }

    public DoStuff()
    {
       // perform custom operation requiring permission
       HelperAssembly.HelperMethods.Method1();

       // do other stuff with low permission level
       ...
       ...
       ...   
    }
}

ヘルパー メソッドを専用の厳密な名前の assemblyに配置し、それらとそのコンテナー クラスを [SecuritySafeCritical] でマークしました。

// HelperAssembly.dll

namespace HelperAssembly
{
    [SecuritySafeCritical]
    public class HelperMethods
    {
        [SecuritySafeCritical]
        public static void Method1()
        {
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)
                .Assert();
            try
            {
                // logic requiring unmanaged code
                ...
            }
            finally
            {
                CodeAccessSecurity.RevertAll();
            }

        }
    }
}

次に、ヘルパー アセンブリをサンドボックスの AppDomain に読み込み、Proxy.DoStuff() を実行します。ヘルパー メソッドが実行され、進行中であることを期待します。

var appDomain = CreateSandbox();

appDomain.Load(typeof(HelperAssembly.HelperMethods).Assembly.FullName);

var proxy = (Proxy)sandbox.CreateInstance(
    typeof(Proxy).Assembly.FullName, 
    typeof(Proxy).FullName).Unwrap();

proxy.DoStuff();

ただし、コードを実行すると、ヘルパー メソッドの Assert() 行で例外が発生します。

未処理の例外: System.InvalidOperationException: セキュリティの透過的なメソッドで CAS アサートを実行できません

この動作の理由は何ですか?また、私がやろうとしていることをどのように達成できますか? 私の理解では、信頼されていない AppDomain のコードはセキュリティ透過的ですが、ヘルパー アセンブリのコードはセキュリティ セーフ クリティカルです。つまり、Assert() でアクセス許可を要求できるはずです。

私は明らかにパズルのピースを見逃しているので、コード アクセス セキュリティをよりよく理解している人に、何が問題なのかを説明してもらう必要があります。どんな助けでも大歓迎です。

4

1 に答える 1