Соображения о безопасности для отражения
Отражение создает возможность получать сведения о типах и членах и получать доступ к членам (то есть вызывать методы и конструкторы, получать и задавать значения свойств, добавлять и удалять обработчики событий и т. д.). Использование отражения для получения сведений о типах и элементах не ограничено. Любой код может использовать отражение для выполнения следующих задач:
Перечислите типы и элемента и изучите их метаданные.
Перечислите и просмотрите сборки и модули.
На использование отражения для доступа к членам, напротив, накладываются ограничения. Начиная с .NET Framework 4, только доверенный код может использовать отражение для доступа к критическим с точки зрения безопасности элементам. Более того, только доверенный код может использовать отражение для доступа к закрытым элементам, недоступным скомпилированному коду напрямую. Наконец, код, использующий отражение для доступа к критически важному для безопасности члену, должен обладать любыми разрешениями, запрошенными критически важным для безопасности членом, как и в случае скомпилированного кода.
В соответствии с необходимыми разрешениями код может использовать отражение для выполнения следующих видов доступа:
Доступ к открытым членам, не являющимся критическими с точки зрения безопасности.
Доступ к закрытым членам, которые доступны компилированному коду, только если не являются критическими с точки зрения безопасности. Примерами подобных закрытых членов являются:
Защищенные члены базовых классов вызывающего кода. (В отражении это называется доступом на уровне семьи.)
Члены internal (члены Friend в Visual Basic) в сборке вызывающего кода. (В отражении это называется доступом на уровне сборки.)
Закрытые члены других экземпляров класса, содержащего вызывающий код.
Например, для кода, выполняемого в изолированном домене приложения, доступ ограничен видами, перечисленными в этом списке, пока домену приложения не будут предоставлены дополнительные разрешения.
Начиная с .NET Framework 2.0 с пакетом обновления 1 (SP1), при попытке доступа к членам, которые обычно недоступны, создается запрос набора прав для целевого объекта и разрешения ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess. Код, выполняемый с полным доверием (например, код в приложении, запущенном из командной строки), может всегда удовлетворять этим разрешениями. (К нему применяются ограничения доступа к членам, критическим с точки зрения безопасности, описанные ниже в данном разделе.)
При необходимости изолированный домен может получить разрешение ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess, как описано в подразделе Доступ к обычно недоступным членам, ниже в данном разделе.
Доступ к членам, критическим с точки зрения безопасности
Член является критическим с точки зрения безопасности, если он обладает атрибутом SecurityCriticalAttribute, если он относится к типу, обладающему атрибутом SecurityCriticalAttribute, или если он входит в сборку, критическую с точки зрения безопасности. Начиная с .NET Framework 4, используются следующие правила доступа к членам, критическим с точки зрения безопасности:
Прозрачный код не может использовать отражение для доступа к членам, критическим с точки зрения безопасности, даже если код является полностью доверенным. Создается исключение MethodAccessException, FieldAccessException или TypeAccessException.
Код, выполняемый с частичным доверием, рассматривается как прозрачный.
Эти правила доступа к члену, критическому с точки зрения безопасности, являются одинаковыми как для прямого доступа из компилированного кода, так и для доступа с помощью отражения.
Код приложения, выполняемый из командной строки, выполняется с полным доверием. Так как этот код не помечен как прозрачный, он может использовать отражение для доступа к членам, критическим с точки зрения безопасности. Когда этот же код выполняется с частичным доверием (например, в изолированном домене приложения), уровень доверия сборки определяет, доступен ли код, критический с точки зрения безопасности: если для сборки используется строгое имя и она установлена в глобальном кэше сборок, эта сборка является доверенной и может вызывать члены, критические с точки зрения безопасности. Если сборка не является доверенной, она становится прозрачной, даже если она не была помечена как прозрачная, и не может получить доступ к членам, критическим с точки зрения безопасности.
Дополнительные сведения о модели безопасности в .NET Framework 4 см. в разделе Изменения системы безопасности в платформе .NET Framework 4.
Отражение и прозрачность
Начиная с .NET Framework 4, среда CLR определяет уровень прозрачности типа или члена по нескольким факторам, включая уровень доверия сборки и уровень доверия домена приложения. Отражение предоставляет свойства IsSecurityCritical, IsSecuritySafeCritical и IsSecurityTransparent, чтобы позволить обнаружить уровень прозрачности типа. В представленной ниже таблице показаны допустимые комбинации этих свойств.
Уровень безопасности |
IsSecurityCritical |
IsSecuritySafeCritical |
IsSecurityTransparent |
---|---|---|---|
Critical |
true |
false |
false |
Критически важный для безопасности |
true |
true |
false |
Прозрачный |
false |
false |
true |
Использовать эти свойства гораздо проще, чем просматривать заметки о безопасности для сборки и ее типов, проверять текущий уровень доверия и предпринимать попытки дублирования правил среды выполнения. Например, один и тот же тип может быть критическим с точки зрения безопасности, если он выполняется из командной строки, или прозрачным с точки зрения безопасности, когда он выполняется в изолированном домене приложения.
Аналогичные свойства имеются в классах MethodBase, FieldInfo, TypeBuilder, MethodBuilder и DynamicMethod. (Для других абстракций отражения и порождаемых отражений атрибуты безопасности применяются к связанным методам. Например, в случае свойств они применяются к методам доступа к свойствам.)
Доступ к обычно недоступным членам
Чтобы использовать отражение для вызова элементов, к которым нельзя получить доступ в соответствии с правилами доступа среды CLR, коду необходимо предоставить два разрешения:
Чтобы разрешить коду вызывать любые закрытые элементы: коду должно быть предоставлено разрешение ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess.
Примечание По умолчанию политика безопасности запрещает использование этого разрешения кодом, который происходит из сети Интернет.Это разрешение никогда не должно предоставляться коду, исходящему из Интернета.
Чтобы разрешить коду вызывать любой закрытый элемент, если только набор прав сборки, содержащей вызываемый элемент, совпадает с набором прав сборки, содержащей вызываемый код, или является его поднабором: коду должно быть предоставлено разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess.
Предположим, домену приложения были предоставлены интернет-разрешения и разрешение ReflectionPermission с ReflectionPermissionFlag.RestrictedMemberAccess, а затем было запущено интернет-приложение с двумя сборками, A и B.
Сборка A может использовать отражение для доступа к закрытым элементам сборки B, потому что набор правил сборки B не содержит таких разрешений, которые были предоставлены сборке A.
Сборка A не может использовать отражение для доступа к закрытым элементам сборок .NET Framework, таких как библиотека mscorlib.dll, потому что mscorlib.dll являются полностью доверенной и поэтому обладает разрешениями, которые не были предоставлены сборке A. Исключение MemberAccessException возникает, когда управление доступом для кода выполняет обход стека во время выполнения.
Сериализация
Для сериализации разрешение SecurityPermission с флагом SecurityPermissionAttribute.SerializationFormatter предоставляет возможность получать и задавать элементы сериализуемых типов независимо от уровня доступа. Это разрешение позволяет программному коду получать и изменять закрытые сведения о состоянии экземпляра. (Помимо наличия соответствующих разрешений, необходимо, чтобы тип был помечен в метаданных как сериализуемый.)
Параметры типа MethodInfo
Избегайте записи открытых членов, принимающих параметры MethodInfo, особенно для доверенного кода. Такие члены могут оказаться более уязвимыми для вредоносного кода. Например, рассмотрим открытый член в доверенном коде, принимающий параметр MethodInfo. Предположим, что открытый член косвенным путем вызывает метод Invoke для передаваемого параметра. Если открытый член не выполняет необходимую проверку разрешений, вызов метода Invoke всегда будет успешным, поскольку система безопасности определит, что вызывающий код является полностью доверенным. Даже если вредоносный код не обладает разрешением для непосредственного вызова метода, он все равно сможет сделать это косвенным образом, вызвав открытый член.
Сведения о версии
Начиная с .NET Framework 4, прозрачный код может не может использовать отражение для доступа к членам, критическим с точки зрения безопасности.
Флаг ReflectionPermissionFlag.RestrictedMemberAccess представлен в .NET Framework 2.0 с пакетом обновления 1 (SP1). Более ранние версии .NET Framework нуждаются во флаге ReflectionPermissionFlag.MemberAccess для кода , использующего отражение в целях доступа к закрытым элементам. Это разрешение, которое никогда не должно предоставляться коду с частичным доверием.
Начиная с .NET Framework 2.0, использование отражения для получения сведений о закрытых типах и элементах не требует никаких разрешений. В более ранних версиях требовался разрешение ReflectionPermission с флагом ReflectionPermissionFlag.TypeInformation.
См. также
Ссылки
Основные понятия
Изменения системы безопасности в платформе .NET Framework 4