Не ссылаться из прозрачного для системы безопасности кода на закрытые критичные в плане безопасности члены
Обновлен: Ноябрь 2007
TypeName |
SecurityTransparentCodeShouldNotReferenceNonpublicSecurityCriticalCode |
CheckId |
CA2129 |
Категория |
Microsoft.Security |
Критическое изменение |
Критическое |
Причина
Методы, помеченные атрибутом SecurityTransparentAttribute вызывают закрытые члены, помеченные как "SecurityCritical". По умолчанию методам назначен атрибут SecurityTransparent.
Описание правила
В версии 2.0 .NET Framework представлена новая функция, которая называется прозрачность. Отдельные методы, поля, интерфейсы, классы и типы могут быть либо прозрачными, либо критическими.
При повышении привилегий безопасности использование прозрачного кода не допускается. Таким образом, любые предоставленные или затребованные от него разрешения передаются через код вызывающему методу или основному приложению домена. Примерами повышения привилегий являются "Asserts", "LinkDemands", "SuppressUnmanagedCode" и небезопасный код.
Целью разделения кода на прозрачный и критический является упрощение процесса аудита безопасности. Аудит, как правило, выполняется на открытых точках входа, поскольку они являются самыми ненадежными и опасными. Помечая небольшие разделы сборки как критические, аудит безопасности может уменьшить число открытых точек входа и критических в плане безопасности разделов кода, повышающих привилегии. Однако чтобы гарантировать точность и полноту аудита, необходимо как можно строже разделять прозрачный и критический код. В противном случае возможность вызова внутреннего критического в плане безопасности кода из прозрачного кода сильно затруднит аудит.
Во время выполнения JIT-компилятор среды CLR проверяет, ссылается или вызывает ли прозрачный код закрытый критический код. При вызове закрытого критического кода из прозрачного кода возникает исключение "MethodAccessException". Подобная ситуация возникает при попытке класса получить доступ к закрытым членам другого класса.
Данное правило анализа кода проверяет все члены и типы в сборке, которые разделены на прозрачные/критические. Правило также помечает все вызовы из прозрачного кода в закрытый критический код, которые не помечены как "SecurityTreatAsSafe".
Устранение нарушений
Чтобы разрешить проблему, следует пометить вызываемый закрытый код как "SecurityCritical" или пометить целевой член/тип как "SecurityTreatAsSafe". При этом код считается открытым и безопасным и проверенным в отношении защиты от вредоносных действий.
Отключение предупреждений
Не следует отключать вывод сообщений о нарушении данного правила.
Пример
Выполнение следующего кода завершится неудачей, поскольку метод "SecondSecurityMethod" является закрытым и помечен как "SecurityCritical". Являясь примером проблемы в системе безопасности, "Assert" в методе "SecondSecurityMethod" запретит полные требования в привилегированных действиях и вызовы для метода "FirstSecurityMethod", ограниченного проверками безопасности, выполняющимися в вызывающем методе.
using System;
using System.Security.Permissions;
namespace SecurityTestClassLibrary
{
public class SecurityTestClass
{
// SecurityTransparent
public void FirstSecurityMethod()
{
SecondSecurityMethod();
}
[System.Security.SecurityCritical]
private void SecondSecurityMethod()
{
// Assert permissions
// do privileged actions, such as method call-outs
}
}
}
Если границы между прозрачным/критическим кодом четко не заданы, метод "FirstSecurityMethod" сможет выполнять все действия метода "SecondSecurityMethod" без проверок безопасности.
Одним из вариантов является просмотр кода метода на предмет безопасности для повышения привилегий и защищенности от вредоносных атак и пометки его как "SecurityTreatAsSafe".
using System;
using System.Security.Permissions;
namespace SecurityTestClassLibrary
{
public class SecurityTestClass
{
// SecurityTransparent
public void FirstSecurityMethod()
{
SecondSecurityMethod();
}
[System.Security.SecurityTreatAsSafe]
[System.Security.SecurityCritical]
private void SecondSecurityMethod()
{
// Assert permissions
// do privileged actions, such as method call-outs
}
}
}
Другим вариантом является пометка метода "Method1" как "Critical". Это расширит ядро критической защиты сборки и увеличит размер аудита безопасности. Также это гарантирует выполнение соответствующего моделирования угроз и анализа кода.
using System;
using System.Security.Permissions;
namespace SecurityTestClassLibrary
{
public class SecurityTestClass
{
[System.Security.SecurityCritical]
public void FirstSecurityMethod()
{
SecondSecurityMethod();
}
[System.Security.SecurityCritical]
private void SecondSecurityMethod()
{
// Assert permissions
// do privileged actions, such as method call-outs
}
}
}