I am using a separate AppDomain
as a sandbox, and trying to execute a method that is constructed via reflection.
When the method is invoked, a SecurityException
is thrown, even though the sandbox AppDomain
has ReflectionPermission(PermissionState.Unrestricted)
set on its PermissionSet
.
The invocation does work when the PermissionSet
is set to PermissionState.Unrestricted
, but that defeats the purpose of a sandbox.
Here's an example that demonstrates the issue:
using System;
using System.Security;
using System.Security.Permissions;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
var person = new Person();
var program = new Program();
var customDomain = program.CreateDomain();
var result = program.Execute(customDomain, (x) =>
{
var type = x.GetType();
var propertyInfo = type.GetProperty("Name");
var method = propertyInfo.GetMethod;
var res = method.Invoke(x, null) as string;
return res;
}, person);
Console.WriteLine(result);
Console.ReadLine();
}
public object Execute(AppDomain domain, Func<object, object> toExecute, params object[] parameters)
{
var proxy = new Proxy(toExecute, parameters);
var result = proxy.Invoke(domain);
return result;
}
private AppDomain CreateDomain()
{
var appDomainSetup = new AppDomainSetup()
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ApplicationName = "UntrustedAppDomain"
};
// Set up permissions
var permissionSet = new PermissionSet(PermissionState.None);
permissionSet.AddPermission(new SecurityPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
// Create the app domain.
return AppDomain.CreateDomain("UntrustedAppDomain", null, appDomainSetup, permissionSet);
}
private sealed class Proxy : MarshalByRefObject
{
private Delegate method;
private object[] args;
private object result;
public Proxy(Delegate method, params object[] parameters)
{
this.method = method;
this.args = parameters;
}
public object Invoke(AppDomain customDomain)
{
customDomain.DoCallBack(Execute);
return this.result;
}
private void Execute()
{
this.result = this.method.DynamicInvoke(this.args);
}
}
}
public class Person
{
public Person()
{
this.Name = "Test Person";
}
public string Name { get; set; }
}
}
Aucun commentaire:
Enregistrer un commentaire