Как отклонить Assert с помощью CAS?
-
03-07-2019 - |
Вопрос
В этом коде я бы хотел, чтобы методу ReadFileSystem было запрещено утверждать разрешение на файловую систему.
Я ожидал, что это вызовет fileIo.Assert(), но это не так.Почему?
using System.Security.Permissions;
static void Main(string[] args)
{
var fileIo = new FileIOPermission(PermissionState.Unrestricted);
var secuPerm = new SecurityPermission(SecurityPermissionFlag.Assertion);
PermissionSet set = new PermissionSet(PermissionState.Unrestricted);
set.AddPermission(fileIo);
set.AddPermission(secuPerm);
set.Deny();
ReadFileSystem();
Console.Read();
}
private static void ReadFileSystem()
{
var fileIo = newFileIOPermission(PermissionState.Unrestricted);
fileIo.Assert();
DirectoryInfo dir = new DirectoryInfo("C:/");
dir.GetDirectories();
}
Обновлять
Отличная ссылка здесь, на CAS: http://blogs.msdn.com/shawnfa/archive/2004/08/25/220458.aspx
Решение
Последующий Assert сводит на нет эффекты Deny.
Возможность утверждать FileIOPermission в основном зависит от того, является ли ваша сборка доверенной.На него не влияет предыдущий запрет FileIOPermission.Оказывается, на него также не влияет предыдущее Deny of the Assertion SecurityPermission. Это связано с тем, что SecurityPermissionFlag.Assertion проверяется как требование времени соединения. Это четко не задокументировано;я нашел это здесь.
Чтобы заставить CLR не доверять вашей сборке для FileIOPermission, вы можете использовать следующее в верхней части файла после операторов using.Когда вы добавите это в свой файл, утверждение не вступит в силу.Это влияет на всю сборку.Более тонкой детализации не существует.
[assembly:FileIOPermission(SecurityAction.RequestRefuse, Unrestricted=true)]
Другие советы
Я думаю, вы можете неправильно понять цель утверждения разрешений.Когда вы утверждаете набор разрешений в CAS, вы фактически говорите: «Я знаю, что делаю...Меня не волнует, какие разрешения находятся глубже в стеке». никогда что вы хотите.Обычно вы хотите потребовать набор разрешений.Это вызовет обход стека, который обнаружит Deny в стеке, а затем вызовет исключение безопасности.
Однако, поскольку в .NET практически все необходимые требования Demands встроены, необходимость в самом деле Demand возникает редко, если только вы не выполняете Asserts (опять же, это редкость) или не написали свой собственный класс Permission.
Хороший вопрос, конечно.Я запустил код и тоже немного озадачен.Я просто трачу час или два на изучение документации и поиск в Google, но безрезультатно.Обратите внимание, что MSDN справляется с этой задачей, выполняя запрос на разрешение утверждения.
Редактировать:ответ двоичного кодера указал мне в правильном направлении.
Права Ассериона просто не эффективно в полнотяговом агрегате.Только если вы добавите следующее в начало файла:
[assembly: SecurityPermissionAttribute(SecurityAction.RequestRefuse, Assertion = true)]
вызов fileIo.Assert() завершится неудачно.
Но в противном случае попытка Deny() разрешения Assertion и следующего атрибута совершенно неэффективна (если только вы явно не Demand() права Assertion).
[SecurityPermissionAttribute(SecurityAction.Deny, Assertion = true)]
private static void ReadFileSystem() {}
В документации указано, что Assert() «имеет некоторые проблемы с безопасностью», и рекомендуется всегда использовать требование перед утверждением:
fileIo.Demand();
fileIo.Assert();
но мне все еще нужно пересмотреть свое отношение к применению принципа наименьших привилегий.