Цель: Мне нужно запустить код в качестве AppDomain с очень ограниченными правами - это не должно иметь никакого доступа ни к чему вообще фантазии или небезопасным, за исключением несколько вспомогательных методов, которые Я определил в другом месте.исключение кода безопасности доступа в ограниченном 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
...
...
...
}
}
Я положил вспомогательные методы в выделенном строгим именем сборки и пометив их и их контейнер класса с [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().
У меня, очевидно, отсутствует кусочек головоломки, поэтому кто-то с лучшим пониманием безопасности доступа к коду объясняет, что происходит не так. Любая помощь приветствуется.
Имеет ли ваша доверенная сборка атрибут AllowPartiallyTrustedCallers? IIRC используется для файлов SecuritySafeCritical ... Кроме того, вы не используете аргумент 'FullTrustAssemblies'' CreateDomain'. Это нормально? – Medinoc
Атрибут [SecuritySafeCritical] игнорируется, если вы не указали название сборки. Project + Properties, вкладка Signing. –
@Medinoc, правильно! Мне нужно было добавить вспомогательную сборку как доверенную в AppDomain.Create и отметить ее как [AllowPartiallyTrustedCallers]. Пожалуйста, продвигайте свой комментарий к ответу, чтобы я мог отметить его как правильно. – staafl