Вопросы безопасности в порождаемом отраженииSecurity Issues in Reflection Emit

Платформа .NET Framework предоставляет три способа создания промежуточного языка Майкрософт (MSIL), каждый из которых имеет собственные вопросы безопасности:The .NET Framework provides three ways to emit Microsoft intermediate language (MSIL), each with its own security issues:

Независимо от способа создания динамического кода для его выполнения необходимы все разрешения, которые требуются типам и методам, используемым этим кодом.Regardless of the way you generate dynamic code, executing the generated code requires all the permissions that are required by the types and methods the generated code uses.

Примечание

Разрешения, необходимые для отражения и порождения кода, были изменены в последующих выпусках .NET Framework.The permissions that are required for reflecting on code and emitting code have changed with succeeding releases of the .NET Framework. Подробнее см. в подразделе Сведения о версиях далее в этом разделе.See Version Information, later in this topic.

Динамические сборкиDynamic Assemblies

Динамические сборки создаются с помощью перегрузок метода AppDomain.DefineDynamicAssembly.Dynamic assemblies are created by using overloads of the AppDomain.DefineDynamicAssembly method. Большинство способов перегрузки этого метода не рекомендуется использовать в .NET Framework 4, так как политика безопасности на уровне компьютера больше не используется.Most overloads of this method are deprecated in the .NET Framework 4, because of the elimination of machine-wide security policy. (См. раздел Изменения системы безопасности.) Остальные перегрузки могут выполняться из любого кода независимо от уровня доверия.(See Security Changes.) The remaining overloads can be executed by any code, regardless of trust level. Эти перегрузки делятся на две группы: те, которые определяют список атрибутов, применяемых к динамической сборке при ее создании, и те, которые этого не делают.These overloads fall into two groups: those that specify a list of attributes to apply to the dynamic assembly when it is created, and those that do not. Если не указать модель прозрачности для сборки, применив атрибут SecurityRulesAttribute при ее создании, эта модель наследуется от порождающей сборки.If you do not specify the transparency model for the assembly, by applying the SecurityRulesAttribute attribute when you create it, the transparency model is inherited from the emitting assembly.

Примечание

Атрибуты, применяемые к динамической сборке после ее создания с помощью метода SetCustomAttribute, не действуют, пока сборка не будет сохранена на диск и повторно загружена в память.Attributes that you apply to the dynamic assembly after it is created, by using the SetCustomAttribute method, do not take effect until the assembly has been saved to disk and loaded into memory again.

Код в динамической сборке может получать доступ к видимым типам и членам в других сборках.Code in a dynamic assembly can access visible types and members in other assemblies.

Примечание

Динамические сборки не используют флаги ReflectionPermissionFlag.MemberAccess и ReflectionPermissionFlag.RestrictedMemberAccess, разрешающие динамическим методам получать доступ к закрытым типам и членам.Dynamic assemblies do not use the ReflectionPermissionFlag.MemberAccess and ReflectionPermissionFlag.RestrictedMemberAccess flags that allow dynamic methods to access nonpublic types and members.

Временные динамические сборки создаются в памяти и никогда не сохраняются на диск, поэтому им не требуются разрешения на доступ к файлам.Transient dynamic assemblies are created in memory and never saved to disk, so they require no file access permissions. Для сохранения динамической сборки на диск требуется разрешение FileIOPermission с соответствующими флагами.Saving a dynamic assembly to disk requires FileIOPermission with the appropriate flags.

Создание динамических сборок из частично доверенного кодаGenerating Dynamic Assemblies from Partially Trusted Code

Рассмотрим условия, в которых сборка с разрешениями на доступ к Интернету может создавать временную динамическую сборку и выполнять ее код.Consider the conditions in which an assembly with Internet permissions can generate a transient dynamic assembly and execute its code:

  • Динамическая сборка использует только открытые типы и члены других сборок.The dynamic assembly uses only public types and members of other assemblies.

  • Разрешения, необходимые для этих типов и членов, включаются в набор прав сборки с частичным доверием.The permissions demanded by those types and members are included in the grant set of the partially trusted assembly.

  • Сборка не сохраняется на диск.The assembly is not saved to disk.

  • Отладочные символы не создаютсяDebug symbols are not generated. (наборы разрешений Internet и LocalIntranet не включают необходимые разрешения).(Internet and LocalIntranet permission sets do not include the necessary permissions.)

Анонимно размещенные динамические методыAnonymously Hosted Dynamic Methods

Анонимно размещенные динамические методы создаются с помощью двух конструкторов DynamicMethod, которые не указывают связанный тип или модуль, DynamicMethod(String, Type, Type[]) и DynamicMethod(String, Type, Type[], Boolean).Anonymously hosted dynamic methods are created by using the two DynamicMethod constructors that do not specify an associated type or module, DynamicMethod(String, Type, Type[]) and DynamicMethod(String, Type, Type[], Boolean). Эти конструкторы размещают динамические методы в предоставляемой системой сборке, которая является полностью доверенной и прозрачный для системы безопасности.These constructors place the dynamic methods in a system-provided, fully trusted, security-transparent assembly. Для использования этих конструкторов или порождения кода для динамических методов разрешения не требуются.No permissions are required to use these constructors or to emit code for the dynamic methods.

Вместо этого при создании анонимно размещаемых динамических методов записывается стек вызовов.Instead, when an anonymously hosted dynamic method is created, the call stack is captured. При создании метода требования безопасности предъявляются к записанному стеку вызовов.When the method is constructed, security demands are made against the captured call stack.

Примечание

Концептуально требования предъявляются во время создания метода.Conceptually, demands are made during the construction of the method. То есть требования могут предъявляться при порождении каждой инструкции MSIL.That is, demands could be made as each MSIL instruction is emitted. В текущей реализации все требования предъявляются при вызове метода DynamicMethod.CreateDelegate или JIT-компилятора, если метод вызывается без вызова CreateDelegate.In the current implementation, all demands are made when the DynamicMethod.CreateDelegate method is called or when the just-in-time (JIT) compiler is invoked, if the method is invoked without calling CreateDelegate.

Если домен приложения допускает такое поведение, анонимно размещенные динамические методы могут пропускать проверки видимости JIT-компилятора, однако действует следующее ограничение: закрытые типы и члены, к которым получает доступ анонимно размещенный динамический метод, должны находиться в сборках, наборы прав которых идентичны набору прав порождающего стека вызовов или являются его подмножествами.If the application domain permits it, anonymously hosted dynamic methods can skip JIT visibility checks, subject to the following restriction: The nonpublic types and members accessed by an anonymously hosted dynamic method must be in assemblies whose grant sets are equal to, or subsets of, the grant set of the emitting call stack. Эта ограниченная возможность пропускать проверки видимости JIT доступна, если домен приложения предоставляет разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess.This restricted ability to skip JIT visibility checks is enabled if the application domain grants ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag.

  • Если метод использует только открытые типы и члены, во время его создания никакие разрешения не требуются.If your method uses only public types and members, no permissions are required during construction.

  • Если вы указываете, что проверки видимости JIT следует пропустить, требование, предъявляемое при создании метода, включает разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess и набор прав сборки, содержащей закрытый член, к которому осуществляется доступ.If you specify that JIT visibility checks should be skipped, the demand that is made when the method is constructed includes ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag and the grant set of the assembly that contains the nonpublic member that is being accessed.

Так как учитывается набор прав закрытого члена, частично доверенный код, которому предоставлено разрешение ReflectionPermissionFlag.RestrictedMemberAccess, не может повысить свои привилегии путем выполнения закрытых членов доверенных сборок.Because the grant set of the nonpublic member is taken into consideration, partially trusted code that has been granted ReflectionPermissionFlag.RestrictedMemberAccess cannot elevate its privileges by executing nonpublic members of trusted assemblies.

Как и для любого другого порожденного кода, для выполнения этого динамического метода необходимы те же разрешения, которые требуются методам, используемым этим динамическим методом.As with any other emitted code, executing the dynamic method requires whatever permissions are demanded by the methods the dynamic method uses.

Системная сборка, в которой размещаются анонимно размещенные динамические методы, использует модель прозрачности SecurityRuleSet.Level1, то есть модель, которая применялась в .NET Framework до версии .NET Framework 4.The system assembly that hosts anonymously-hosted dynamic methods uses the SecurityRuleSet.Level1 transparency model, which is the transparency model that was used in the .NET Framework before the .NET Framework 4.

Дополнительные сведения см. в описании класса DynamicMethod.For more information, see the DynamicMethod class.

Создание анонимно размещенных динамических методов из частично доверенного кодаGenerating Anonymously Hosted Dynamic Methods from Partially Trusted Code

Рассмотрим условия, в которых сборка с разрешениями на доступ к Интернету может создавать анонимно размещенный динамический метод и выполнять его.Consider the conditions in which an assembly with Internet permissions can generate an anonymously hosted dynamic method and execute it:

  • Динамический метод использует только открытые типы и члены.The dynamic method uses only public types and members. Если его набор прав включает ReflectionPermissionFlag.RestrictedMemberAccess, он может использовать закрытые типы и члены любой сборки, набор прав которой идентичен набору прав порождающей сборки или является его подмножеством.If its grant set includes ReflectionPermissionFlag.RestrictedMemberAccess, it can use nonpublic types and members of any assembly whose grant set is equal to, or a subset of, the grant set of the emitting assembly.

  • Разрешения, необходимые всем типам и членам, используемым динамическим методом, включены в набор прав сборки с частичным доверием.The permissions that are required by all the types and members used by the dynamic method are included in the grant set of the partially trusted assembly.

Примечание

Динамические методы не поддерживают отладочные символы.Dynamic methods do not support debug symbols.

Динамические методы, связанные с существующими сборкамиDynamic Methods Associated with Existing Assemblies

Чтобы связать динамический метод с типом или модулем в существующей сборке, используйте любой из конструкторов DynamicMethod, который указывает связанный тип или модуль.To associate a dynamic method with a type or module in an existing assembly, use any of the DynamicMethod constructors that specify the associated type or module. Разрешения, необходимые для вызова этих конструкторов, могут быть разными, так как при связывании динамического метода с существующим типом или модулем он получает доступ к закрытым типам и членам.The permissions that are required to call these constructors vary, because associating a dynamic method with an existing type or module gives the dynamic method access to nonpublic types and members:

  • Динамический метод, связанный с типом, имеет доступ ко всем членам этого типа, даже к закрытым, а также ко всем внутренним типам и членам в сборке, содержащей связанный тип.A dynamic method that is associated with a type has access to all members of that type, even private members, and to all internal types and members in the assembly that contains the associated type.

  • Динамический метод, связанный с модулем, имеет доступ ко всем типам и членам internal (Friend в Visual Basic, assembly в метаданных среды CLR) в модуле.A dynamic method that is associated with a module has access to all the internal types and members (Friend in Visual Basic, assembly in common language runtime metadata) in the module.

Кроме того, можно использовать конструктор, который задает возможность пропускать проверки видимости JIT-компилятора.In addition, you can use a constructor that specifies the ability to skip the visibility checks of the JIT compiler. Это позволяет динамическому методу получать доступ ко всем типам и членам во всех сборках независимо от уровня доступа.Doing so gives your dynamic method access to all types and members in all assemblies, regardless of access level.

Разрешения, необходимые конструктору, зависят от уровня доступа, который вы намерены предоставить динамическому методу.The permissions demanded by the constructor depend on how much access you decide to give your dynamic method:

Несмотря на то что элементы в этом списке описываются в терминах набора прав порождающей сборки, помните, что требования предъявляются к полному стеку вызовов, включая границы домена приложения.Although the items in this list are described in terms of the grant set of the emitting assembly, remember that the demands are made against the full call stack, including the application domain boundary.

Дополнительные сведения см. в описании класса DynamicMethod.For more information, see the DynamicMethod class.

Создание динамических методов из частично доверенного кодаGenerating Dynamic Methods from Partially Trusted Code

Примечание

Для создания динамических методов из частично доверенного кода рекомендуется использовать анонимно размещенные динамические методы.The recommended way to generate dynamic methods from partially trusted code is to use anonymously hosted dynamic methods.

Рассмотрим условия, в которых сборка с разрешениями на доступ к Интернету может создавать динамический метод и выполнять его.Consider the conditions in which an assembly with Internet permissions can generate a dynamic method and execute it:

  • Либо динамический метод связан с порождающим его модулем или типом, либо его набор прав включает ReflectionPermissionFlag.RestrictedMemberAccess и он связан с модулем в сборке, набор прав которой идентичен набору прав порождающей сборки или является его подмножеством.Either the dynamic method is associated with the module or type that emits it, or its grant set includes ReflectionPermissionFlag.RestrictedMemberAccess and it is associated with a module in an assembly whose grant set is equal to, or a subset of, the grant set of the emitting assembly.

  • Динамический метод использует только открытые типы и члены.The dynamic method uses only public types and members. Если его набор прав включает ReflectionPermissionFlag.RestrictedMemberAccess и он связан с модулем в сборке, набор прав которой идентичен набору прав порождающей сборки или является его подмножеством, он может использовать типы и члены, помеченные как internal (Friend в Visual Basic, assembly в метаданных среды CLR) в связанном модуле.If its grant set includes ReflectionPermissionFlag.RestrictedMemberAccess and it is associated with a module in an assembly whose grant set is equal to, or a subset of, the grant set of the emitting assembly, it can use types and members marked internal (Friend in Visual Basic, assembly in common language runtime metadata) in the associated module.

  • Разрешения, необходимые всем типам и членам, используемым динамическим методом, включены в набор прав сборки с частичным доверием.The permissions demanded by all the types and members used by the dynamic method are included in the grant set of the partially trusted assembly.

  • Динамический метод не пропускает проверки видимости JIT-компилятора.The dynamic method does not skip JIT visibility checks.

Примечание

Динамические методы не поддерживают отладочные символы.Dynamic methods do not support debug symbols.

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

Начиная с .NET Framework 4 политика безопасности на уровне компьютера больше не используется, и механизмом обеспечения безопасности по умолчанию становится прозрачность безопасности.Starting with the .NET Framework 4, machine-wide security policy is eliminated and security transparency becomes the default enforcement mechanism. См. раздел Изменения системы безопасности.See Security Changes.

Начиная с .NET Framework 2.0 с пакетом обновления 1 (SP1), разрешение ReflectionPermission с флагом ReflectionPermissionFlag.ReflectionEmit больше не требуется при порождении динамических сборок и динамических методов.Starting with the .NET Framework 2.0 Service Pack 1, ReflectionPermission with the ReflectionPermissionFlag.ReflectionEmit flag is no longer required when emitting dynamic assemblies and dynamic methods. Этот флаг необходим во всех более ранних версиях платформы .NET Framework.This flag is required in all earlier versions of the .NET Framework.

Примечание

Разрешение ReflectionPermission с флагом ReflectionPermissionFlag.ReflectionEmit включается по умолчанию в именованные наборы разрешений FullTrust и LocalIntranet, но не в набор разрешений Internet.ReflectionPermission with the ReflectionPermissionFlag.ReflectionEmit flag is included by default in the FullTrust and LocalIntranet named permission sets, but not in the Internet permission set. Таким образом, в более ранних версиях платформы .NET Framework библиотеку можно использовать с разрешениями на доступ к Интернету только в том случае, если она выполняет Assert для ReflectionEmit.Therefore, in earlier versions of the .NET Framework, a library can be used with Internet permissions only if it executes an Assert for ReflectionEmit. Такие библиотеки требуют тщательной проверки безопасности, так как ошибки в коде могут стать причиной уязвимости.Such libraries require careful security review because coding errors could result in security holes. Платформа .NET Framework 2.0 с пакетом обновления 1 (SP1) позволяет создавать код в сценариях частичного доверия без предъявления каких-либо требований к безопасности, так как создание кода по сути не является привилегированной операцией.The .NET Framework 2.0 SP1 allows code to be emitted in partial trust scenarios without issuing any security demands, because generating code is not inherently a privileged operation. То есть созданный код имеет не больше разрешений, чем породившая его сборка.That is, the generated code has no more permissions than the assembly that emits it. Это позволяет библиотекам, порождающим код, сохранять прозрачность для системы безопасности, что устраняет необходимость в утверждении перечисления ReflectionEmit и упрощает задачу написания безопасной библиотеки.This allows libraries that emit code to be security transparent and removes the need to assert ReflectionEmit, which simplifies the task of writing a secure library.

Кроме того, в .NET Framework 2.0 с пакетом обновления 1 (SP1) появился флаг ReflectionPermissionFlag.RestrictedMemberAccess для доступа к закрытым типам и членам из частично доверенных динамических методов.In addition, the .NET Framework 2.0 SP1 introduces the ReflectionPermissionFlag.RestrictedMemberAccess flag for accessing nonpublic types and members from partially trusted dynamic methods. Более ранние версии платформы .NET Framework требуют флаг ReflectionPermissionFlag.MemberAccess для динамических методов, которые обращаются к закрытым типам и членам; это разрешение, которое никогда не должно предоставляться частично доверенному коду.Earlier versions of the .NET Framework require the ReflectionPermissionFlag.MemberAccess flag for dynamic methods that access nonpublic types and members; this is a permission that should never be granted to partially trusted code.

Наконец, в .NET Framework 2.0 с пакетом обновления 1 (SP1) реализованы анонимно размещенные методы.Finally, the .NET Framework 2.0 SP1 introduces anonymously hosted methods.

Получение сведений о типах и членахObtaining Information on Types and Members

Начиная с .NET Framework 2.0 для получения сведений о закрытых типах и членах никакие разрешения не требуются.Starting with the .NET Framework 2.0, no permissions are required to obtain information about nonpublic types and members. Для получения сведений, необходимых для порождения динамических методов, используется отражение.Reflection is used to obtain information needed to emit dynamic methods. Например, объекты MethodInfo используются для порождения вызовов метода.For example, MethodInfo objects are used to emit method calls. Более ранние версии платформы .NET Framework требуют ReflectionPermission с флагом ReflectionPermissionFlag.TypeInformation.Earlier versions of the .NET Framework require ReflectionPermission with the ReflectionPermissionFlag.TypeInformation flag. Дополнительные сведения см. в разделе Соображения о безопасности для отражения.For more information, see Security Considerations for Reflection.

См. такжеSee also