Sto scrivendo un sistema di plugin per eseguire codice non attendibile fornito dal client nella mia applicazione server (C#, .NET 4.0). Per fare questo, eseguo ogni plugin in un nuovo AppDomain sandbox.C# AppDomain Eccezione di sicurezza sandbox quando si sottoscrive eventi di dominio
Tuttavia, sono bloccato su un'eccezione di sicurezza che non capisco davvero il motivo. Ho fatto un esempio un'applicazione console semplificato per illustrare il problema:
namespace SandboxTest
{
class Program
{
static void Main(string[] args)
{
Sandbox sandbox = new Sandbox();
Console.ReadLine();
}
}
class Sandbox
{
AppDomain domain;
public Sandbox()
{
PermissionSet ps = new PermissionSet(PermissionState.None);
ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
try
{
domain = AppDomain.CreateDomain("Sandbox", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation, ps);
domain.AssemblyLoad += new AssemblyLoadEventHandler(domain_AssemblyLoad);
domain.AssemblyResolve += new ResolveEventHandler(domain_AssemblyResolve);
}
catch(Exception e)
{
Trace.WriteLine(e.ToString());
throw e;
}
}
static Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return null;
}
static void domain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
}
}
}
Al momento dell'esecuzione di questo codice, sto ottenendo la seguente eccezione sulla linea domain.AssemblyLoad:
A first chance exception of type 'System.Security.SecurityException' occurred in SandboxTest.exe
'SandboxTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Object assemblyOrString, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
at System.Security.CodeAccessSecurityEngine.CheckHelper(PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, Object assemblyOrString, SecurityAction action, Boolean throwException)
at System.Security.CodeAccessSecurityEngine.CheckHelper(CompressedStack cs, PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action)
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
at System.Security.CodeAccessPermission.Demand()
at System.DelegateSerializationHolder.GetDelegateSerializationInfo(SerializationInfo info, Type delegateType, Object target, MethodInfo method, Int32 targetIndex)
at System.MulticastDelegate.GetObjectData(SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj, String& typeName, String& assemName, String[]& fieldNames, Object[]& fieldValues)
at System.AppDomain.add_AssemblyLoad(AssemblyLoadEventHandler value)
at SandboxTest.Sandbox..ctor() in C:\Dev\Projects\Botfield\SandboxTest\Program.cs:line 36
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.ReflectionPermission
The first permission that failed was:
<IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="MemberAccess"/>
The demand was for:
<IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="MemberAccess"/>
The granted set of the failing assembly was:
<PermissionSet class="System.Security.PermissionSet"
version="1">
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="Execution"/>
</PermissionSet>
La mia ipotesi migliore è che c'è un codice di sottoscrizione di eventi sotto il cofano che si sta eseguendo nel nuovo AppDomain sandbox senza le autorizzazioni di sicurezza necessarie, ma non so come aggirarlo senza dare piena capacità di riflessione all'appDomain in modalità sandbox. Qualcuno ha un suggerimento o una spiegazione, per favore?