Соображения о безопасности для отраженияSecurity Considerations for Reflection

Отражение дает возможность получать информацию о типах и членах, а также обращаться к членам (то есть вызывать методы и конструкторы для получения и задания значений свойств, добавления и удаления обработчиков событий и т. д.).Reflection provides the ability to obtain information about types and members, and to access members (that is, to call methods and constructors, to get and set property values, to add and remove event handlers, and so on). Использование отражения для получения информации о типах и членах не ограничено.The use of reflection to obtain information about types and members is not restricted. В любом коде отражение можно использовать для выполнения следующих задач:All code can use reflection to perform the following tasks:

  • перечисления типов и членов и просмотра их метаданных;Enumerate types and members, and examine their metadata.

  • перечисления и просмотра сборок и модулей.Enumerate and examine assemblies and modules.

На использование отражения для доступа к членам, напротив, накладываются ограничения.Using reflection to access members, by contrast, is subject to restrictions. Начиная с .NET Framework 4 только полностью доверенный код может использовать отражение для доступа к членам, критически важным с точки зрения безопасности.Beginning with the .NET Framework 4, only trusted code can use reflection to access security-critical members. Кроме того, только полностью доверенный код может использовать отражение для доступа к закрытым членам, которые недоступны компилированному коду непосредственно.Furthermore, only trusted code can use reflection to access nonpublic members that would not be directly accessible to compiled code. Наконец, код, который использует отражение для доступа к критическим с точки зрения безопасности членам, должен иметь все разрешения, требуемые этим членом, то есть ситуация такая же, как с компилированным кодом.Finally, code that uses reflection to access a safe-critical member must have whatever permissions the safe-critical member demands, just as with compiled code.

В зависимости от необходимых разрешений код может использовать отражение для осуществления следующих видов доступа:Subject to necessary permissions, code can use reflection to perform the following kinds of access:

  • доступ к открытым членам, которые не являются критическими с точки зрения безопасности;Access public members that are not security-critical.

  • доступ к закрытым членам, которые доступны скомпилированному коду, только если не являются критическими с точки зрения безопасности.Access nonpublic members that would be accessible to compiled code, if those members are not security-critical. Примерами подобных закрытых членов являются:Examples of such nonpublic members include:

    • защищенные члены базовых классов вызывающего кодаProtected members of the calling code's base classes. (в отражении это называется доступом на уровне семейства);(In reflection, this is referred to as family-level access.)

    • члены internal (члены Friend в Visual Basic) в сборке вызывающего кодаinternal members (Friend members in Visual Basic) in the calling code's assembly. (в отражении это называется доступом на уровне сборки);(In reflection, this is referred to as assembly-level access.)

    • закрытые члены других экземпляров класса, содержащего вызывающий код.Private members of other instances of the class that contains the calling code.

Например, для кода, выполняемого в изолированном домене приложения, доступ ограничен видами, перечисленными в этом списке, пока домену приложения не будут предоставлены дополнительные разрешения.For example, code that is run in a sandboxed application domain is limited to the access described in this list, unless the application domain grants additional permissions.

Начиная с .NET Framework 2.0 с пакетом обновления 1 (SP1) при попытке доступа к членам, которые обычно недоступны, запрашивается набор прав для целевого объекта и разрешения ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess.Starting with the .NET Framework 2.0 Service Pack 1, attempting to access members that are normally inaccessible generates a demand for the grant set of the target object plus ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag. Код, выполняемый с полным доверием (например, код в приложении, которое запускается из командной строки), может всегда удовлетворять этим разрешениям.Code that is running with full trust (for example, code in an application that is launched from the command line) can always satisfy these permissions. (К нему применяются ограничения доступа к членам, критическим с точки зрения безопасности, описанные ниже в данном разделе.)(This is subject to limitations in accessing security-critical members, as described later in this article.)

При необходимости изолированный домен приложения может предоставить разрешение ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess, как описано в разделе Доступ к обычно недоступным членам далее в этой статье.Optionally, a sandboxed application domain can grant ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag, as described in the section Accessing Members That Are Normally Inaccessible, later in this article.

Доступ к членам, критическим с точки зрения безопасностиAccessing Security-Critical Members

Член является критическим с точки зрения безопасности, если у него есть атрибут SecurityCriticalAttribute, если он относится к типу с атрибутом SecurityCriticalAttribute или если он находится в сборке, критической с точки зрения безопасности.A member is security-critical if it has the SecurityCriticalAttribute, if it belongs to a type that has the SecurityCriticalAttribute, or if it is in a security-critical assembly. Начиная с версии NET Framework 4 в отношении доступа к членам, критически важным с точки зрения безопасности, применяются описанные ниже правила.Beginning with the .NET Framework 4, the rules for accessing security-critical members are as follows:

  • Прозрачный код не может использовать отражение для доступа к членам, критическим с точки зрения безопасности, даже если он является полностью доверенным.Transparent code cannot use reflection to access security-critical members, even if the code is fully trusted. Создается исключение MethodAccessException, FieldAccessException или TypeAccessException.A MethodAccessException, FieldAccessException, or TypeAccessException is thrown.

  • Код, выполняемый с частичным доверием, рассматривается как прозрачный.Code that is running with partial trust is treated as transparent.

Эти правила являются одинаковыми как для прямого доступа к члену, критическому с точки зрения безопасности, из скомпилированного кода, так и для доступа с помощью отражения.These rules are the same whether a security-critical member is accessed directly by compiled code, or accessed by using reflection.

Код приложения, который запускается из командной строки, выполняется с полным доверием.Application code that is run from the command line runs with full trust. Если код не помечен как прозрачный, он может использовать отражение для доступа к членам, критическим с точки зрения безопасности.As long as it is not marked as transparent, it can use reflection to access security-critical members. При выполнении того же кода с частичным доверием (например, в изолированном домене приложения) уровень доверия сборки определяет, может ли она получить доступ к коду, критическому с точки зрения безопасности: если сборка имеет строгое имя и установлена в глобальном кэше сборок, она является доверенной и может вызывать члены, критические с точки зрения безопасности.When the same code is run with partial trust (for example, in a sandboxed application domain) the assembly's trust level determines whether it can access security-critical code: If the assembly has a strong name and is installed in the global assembly cache, it is a trusted assembly and can call security-critical members. Если код не является доверенным, он становится прозрачным даже в том случае, если не был помечен как прозрачный, и не может получить доступ к членам, критическим с точки зрения безопасности.If it is not trusted, it becomes transparent even though it was not marked as transparent, and it cannot access security-critical members.

Подробнее о модели безопасности в .NET Framework 4 см. в разделе Изменения системы безопасности.For more information about the security model in the .NET Framework 4, see Security Changes.

Отражение и прозрачностьReflection and Transparency

Начиная с версии .NET Framework 4 среда CLR определяет уровень прозрачности типа или члена на основе нескольких факторов, включая уровень доверия сборки и уровень доверия домена приложения.Beginning with the .NET Framework 4, the common language runtime determines the transparency level of a type or member from several factors, including the trust level of the assembly and the trust level of the application domain. Отражение предоставляет свойства IsSecurityCritical, IsSecuritySafeCritical и IsSecurityTransparent, которые позволяют определить уровень прозрачности типа.Reflection provides the IsSecurityCritical, IsSecuritySafeCritical, and IsSecurityTransparent properties to enable you to discover the transparency level of a type. В таблице ниже приведены допустимые сочетания этих свойств.The following table shows the valid combinations of these properties.

Уровень безопасностиSecurity level IsSecurityCriticalIsSecurityCritical IsSecuritySafeCriticalIsSecuritySafeCritical IsSecurityTransparentIsSecurityTransparent
CriticalCritical true false false
Критический в плане безопасностиSafe-critical true true false
ПрозрачныйTransparent false false true

Использовать эти свойства гораздо проще, чем просматривать заметки о безопасности для сборки и ее типов, проверять текущий уровень доверия и пытаться дублировать правила среды выполнения.Using these properties is much simpler than examining the security annotations of an assembly and its types, checking the current trust level, and attempting to duplicate the runtime's rules. Например, один и тот же тип может быть критическим с точки зрения безопасности при запуске из командной строки или прозрачным для системы безопасности при запуске в изолированном домене приложения.For example, the same type can be security-critical when it is run from the command line, or security-transparent when it is run in a sandboxed application domain.

Аналогичные свойства имеются в классах MethodBase, FieldInfo, TypeBuilder, MethodBuilder и DynamicMethod.There are similar properties on the MethodBase, FieldInfo, TypeBuilder, MethodBuilder, and DynamicMethod classes. (Для других отражений и абстракций порождаемых отражений атрибуты безопасности применяются к связанным методам; например, в случае свойств они применяются к методам доступа к свойствам).(For other reflection and reflection emit abstractions, security attributes are applied to the associated methods; for example, in the case of properties they are applied to the property accessors.)

Доступ к обычно недоступным членамAccessing Members That Are Normally Inaccessible

Чтобы использовать отражение для вызова членов, которые недоступны в соответствии с правилами доступности среды CLR, коду необходимо предоставить одно из двух разрешений.To use reflection to invoke members that are inaccessible according to the accessibility rules of the common language runtime, your code must be granted one of two permissions:

  • Чтобы разрешить коду вызывать любой закрытый член, ему нужно предоставить разрешение ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess.To allow code to invoke any nonpublic member:Your code must be granted ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag.

    Примечание

    По умолчанию политика безопасности отказывает в предоставлении этого разрешения коду, полученному из Интернета.By default, security policy denies this permission to code that originates from the Internet. Это разрешение ни в коем случае нельзя предоставлять коду, источником которого является Интернет.This permission should never be granted to code that originates from the Internet.

  • Чтобы разрешить коду вызывать любой закрытый член, только если набор прав сборки, содержащей вызываемый член, идентичен набору прав сборки, содержащей вызывающий код, или является его подмножеством: Коду необходимо предоставить разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess.To allow code to invoke any nonpublic member, as long as the grant set of the assembly that contains the invoked member is the same as, or a subset of, the grant set of the assembly that contains the invoking code: Your code must be granted ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag.

Предположим, вы предоставляете домену приложения разрешения на доступ к Интернету плюс разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess, а затем запускаете веб-приложение с двумя сборками, A и B.For example, suppose you grant an application domain Internet permissions plus ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag, and then run an Internet application with two assemblies, A and B.

  • Сборка A может использовать отражение для доступа к закрытым членам сборки B, так как набор прав сборки B не включает какие-либо разрешения, которые не предоставлены сборке A.Assembly A can use reflection to access private members of assembly B, because the grant set of assembly B does not include any permissions that A has not been granted.

  • Сборка A не может использовать отражение для доступа к закрытым членам сборок платформы .NET Framework, таких как mscorlib.dll, так как mscorlib.dll является полностью доверенной и поэтому обладает разрешениями, которые не были предоставлены сборке A. Возникает исключение MemberAccessException, когда управление доступом для кода выполняет обход стека в среде выполнения.Assembly A cannot use reflection to access private members of .NET Framework assemblies such as mscorlib.dll, because mscorlib.dll is fully trusted and therefore has permissions that have not been granted to assembly A. A MemberAccessException is thrown when code access security walks the stack at run time.

СериализацияSerialization

Что касается сериализации, разрешение SecurityPermission с флагом SecurityPermissionAttribute.SerializationFormatter предоставляет возможность получать и задавать члены сериализуемых типов независимо от доступности.For serialization, SecurityPermission with the SecurityPermissionAttribute.SerializationFormatter flag provides the ability to get and set members of serializable types, regardless of accessibility. Это разрешение позволяет коду обнаруживать и изменять закрытое состояние экземпляра.This permission enables code to discover and change the private state of an instance. (Помимо наличия соответствующих разрешений тип должен быть помечен как сериализуемый в метаданных.)(In addition to being granted the appropriate permissions, the type must be marked as serializable in metadata.)

Параметры типа MethodInfoParameters of Type MethodInfo

Избегайте написания открытых членов, принимающих параметры MethodInfo, особенно для доверенного кода.Avoid writing public members that take MethodInfo parameters, especially for trusted code. Такие члены могут оказаться более уязвимыми для вредоносного кода.Such members might be more vulnerable to malicious code. Например, рассмотрим открытый член в коде с высоким уровнем доверия, принимающий параметр MethodInfo.For example, consider a public member in highly trusted code that takes a MethodInfo parameter. Предположим, что открытый член косвенно вызывает метод Invoke для предоставленного параметра.Assume that the public member indirectly calls the Invoke method on the supplied parameter. Если открытый член не выполняет необходимые проверки разрешений, вызов метода Invoke всегда будет успешным, так как система безопасности определяет, что вызывающий объект является полностью доверенным.If the public member does not perform the necessary permission checks, the call to the Invoke method will always succeed, because the security system determines that the caller is highly trusted. Даже если вредоносный код не имеет разрешения на прямой вызов метода, он по-прежнему может сделать это косвенным образом, вызвав открытый член.Even if malicious code does not have the permission to directly invoke the method, it can still do so indirectly by calling the public member.

Сведения о версииVersion Information

  • Начиная с NET Framework 4 прозрачный код не может использовать отражение для доступа к членам, критически важным с точки зрения безопасности.Beginning with the .NET Framework 4, transparent code cannot use reflection to access security-critical members.

  • Флаг ReflectionPermissionFlag.RestrictedMemberAccess впервые появился в .NET Framework 2.0 с пакетом обновления 1 (SP1).The ReflectionPermissionFlag.RestrictedMemberAccess flag is introduced in the .NET Framework 2.0 Service Pack 1. Более ранние версии платформы .NET Framework требуют флаг ReflectionPermissionFlag.MemberAccess для кода, который использует отражение для доступа к закрытым членам.Earlier versions of the .NET Framework require the ReflectionPermissionFlag.MemberAccess flag for code that uses reflection to access nonpublic members. Это разрешение, которое ни в коем случае нельзя предоставлять коду с частичным доверием.This is a permission that should never be granted to partially trusted code.

  • Начиная с .NET Framework 2.0 использование отражения для получения сведений о закрытых типах и членах не требует никаких разрешений.Beginning with the .NET Framework 2.0, using reflection to obtain information about nonpublic types and members does not require any permissions. В более ранних версиях для этого требовалось разрешение ReflectionPermission с флагом ReflectionPermissionFlag.TypeInformation.In earlier versions, ReflectionPermission with the ReflectionPermissionFlag.TypeInformation flag is required.

См. такжеSee also