CA2147: прозрачные методы могут не использовать утверждения безопасности
TypeName |
SecurityTransparentCodeShouldNotAssert |
CheckId |
CA2147 |
Категория |
Microsoft.Security |
Критическое изменение |
Критическое изменение |
Причина
Код, помеченный атрибутом SecurityTransparentAttribute, не обладает достаточными разрешениями для утверждения.
Описание правила
В этом правиле выполняется анализ всех методов и типов в сборки, которая либо на 100% прозрачная, либо смешанная (прозрачная и критическая); правило помечает декларативное и императивное использование Assert.
Во время выполнения любые вызовы Assert из прозрачного кода приведут к возникновению InvalidOperationException. Это может произойти и в прозрачных на 100% сборках, и в смешанных сборках (прозрачных и критических), где метод или тип объявляется прозрачным, но включает декларативный или императивный вызов Assert.
В версии 2.0 .NET Framework представлена новая функция, которая называется прозрачность. Отдельные методы, поля, интерфейсы, классы и типы могут быть либо прозрачными, либо критическими.
При повышении привилегий безопасности использование прозрачного кода не допускается. Поэтому все предоставляемые и запрашиваемые разрешения автоматически передаются через код вызывающему объекту или основному домену приложения. Пример передачи включает элементы Assert, LinkDemand, SuppressUnmanagedCode и код unsafe.
Устранение нарушений
Чтобы устранить эту проблему, либо пометьте код, вызывающий Assert с помощью SecurityCriticalAttribute как SecurityCritical, либо удалите Assert.
Отключение предупреждений
Не следует отключать вывод предупреждений для этого правила.
Пример
Код выдаст сбой, если SecurityTestClass является прозрачным при создании методом Assert исключения InvalidOperationException.
using System;
using System.Security;
using System.Security.Permissions;
namespace TransparencyWarningsDemo
{
public class TransparentMethodsUseSecurityAssertsClass
{
// CA2147 violation - transparent code using a security assert declaratively. This can be fixed by
// any of:
// 1. Make DeclarativeAssert critical
// 2. Make DeclarativeAssert safe critical
// 3. Remove the assert attribute
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
public void DeclarativeAssert()
{
}
public void ImperativeAssert()
{
// CA2147 violation - transparent code using a security assert imperatively. This can be fixed by
// any of:
// 1. Make ImperativeAssert critical
// 2. Make ImperativeAssert safe critical
// 3. Remove the assert call
new PermissionSet(PermissionState.Unrestricted).Assert();
}
}
}
Одним из вариантов является анализ кода метода SecurityTransparentMethod в приведенном ниже примере, и если метод считается безопасным для повышения уровня прав, пометьте SecurityTransparentMethod как критичный в плане безопасности. Это требует выполнения подробного, полного и свободного от ошибок безопасности аудита метода вместе с любыми вызовами, которые возникают в этом методе в Assert:
using System;
using System.Security.Permissions;
namespace SecurityTestClassLibrary
{
public class SecurityTestClass
{
[System.Security.SecurityCritical]
void SecurityCriticalMethod()
{
new FileIOPermission(PermissionState.Unrestricted).Assert();
// perform I/O operations under Assert
}
}
}
Другой возможный вариант — удалить Assert из кода и направить все последующие запросы разрешений на ввод-вывод файлов за пределы метода SecurityTransparentMethod вызывающего объекта. Это разрешает выполнение проверок безопасности. В этом случае аудит безопасности не нужен, поскольку запросы разрешений будут переданы вызывающему объекту или домену приложения. Управление запросами разрешений осуществляется посредством политики безопасности, среды размещения и разрешений кода.