Вопросы безопасности в порождаемом отражении
.NET Framework предоставляет три способа выпуска MSIL, каждый из которых имеет собственные вопросы безопасности:
Динамические сборки
Анонимно размещенные динамические методы
Динамические методы, связанные с текущими сборками
Независимо от способа создания динамического кода, для выполнения созданного кода необходимы все разрешения, которые требуется типами и методами, используемыми в этом коде.
![]() |
---|
Разрешения, необходимые для отражения кода и выпуска кода, изменились с последующими выпусками .NET Framework.См. подраздел Сведения о версии, приведенный ниже. |
Динамические сборки
Динамические сборки создаются с помощью перегрузок метода AppDomain.DefineDynamicAssembly. Большинство перегрузок метода не рекомендуется использовать в .NET Framework 4, поскольку политика безопасности на уровне компьютера больше не используется. (См. Изменения системы безопасности в платформе .NET Framework 4). Оставшиеся перегрузки могут быть выполнены с помощью любого кода независимо от уровня доверия. Эти перегрузки делятся на две группы: перегрузки, которые задают список атрибутов для применения к динамической сборке при ее создании, и остальные перегрузки, которые этого не делают. Если при создании сборке не задать модель прозрачности с помощью атрибута SecurityRulesAttribute, модель прозрачности наследуется из выпускающей сборки.
![]() |
---|
Атрибуты, которые применены к динамической сборке после ее создания с помощью метода SetCustomAttribute, вступают в силу только после сохранения сборки на диск и ее повторной загрузки в память. |
Код в динамической сборке может получить доступ к видимым типам и элементам в других сборках.
![]() |
---|
Динамические сборки не используют флаги ReflectionPermissionFlag.MemberAccess и ReflectionPermissionFlag.RestrictedMemberAccess, с помощью которых динамические методы могут получать доступ к закрытым типам и элементам. |
Временные динамические сборки создаются в памяти и никогда не сохраняются на диске, поэтому для них не требуется разрешения на доступ к файлам. Для сохранения динамической сборки на диск требуется разрешение FileIOPermission с соответствующими флагами.
Создание динамических сборок из кода с частичным доверием
Рассмотрите условия, при которых сборка с интернет-разрешениями может создать временную динамическую сборку и выполнить код:
Динамическая сборка использует только открытые типы и элементы других сборок.
Разрешения, необходимые для этих типов и элементов, включаются в набор прав сборки с частичным доверием.
Сборка не сохраняется на диск.
Символы отладки не создаются. (Наборы разрешений Internet и LocalIntranet не содержат требуемых разрешений.)
Анонимно размещенные динамические методы
Анонимно размещенные динамические методы созданы с помощью двух конструкторов DynamicMethod, которые не указывают связанный тип или модуль: DynamicMethod(String, Type, Type[]) и DynamicMethod(String, Type, Type[], Boolean). Эти конструкторы размещают динамические методы в сборке, которая предоставляется системой, имеет полное доверие и является прозрачной для системы безопасности. Чтобы использовать эти конструкторы или выпускать код для динамических методов, никаких разрешений не требуется.
Вместо этого при создании анонимно размещенных динамических методов перехватывается стек вызовов. При создании метода требования безопасности предъявляются к перехваченному стеку вызовов.
![]() |
---|
Концептуально требования предъявляются во время создания метода.То есть требования могут предъявляться при выпуске каждой инструкции MSIL.В текущей реализации все требования предъявляются при вызове метода DynamicMethod.CreateDelegate или при вызове JIT-компилятора, если метод вызывается без обращения к методу CreateDelegate. |
Если домен приложения разрешает, анонимно размещенные динамические методы могут пропускать проверки видимости, выполняемые JIT-компилятором, и подлежат следующему ограничению: закрытые типы и элементы, к которым получает доступ анонимно размещенные динамические методы, должны находиться в сборках, наборы прав которых равны набору прав выпускающего стека вызовов или являются его подмножествами. Эта ограниченная возможность пропуска проверок видимости используется, если домен приложения предоставляет разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess.
Если в методе используются только открытые типы и элементы, во время создания никаких разрешений не требуется.
Если отменить проверки видимости, выполняемые JIT-компилятором, требование, предъявляемое при создании метода, содержит разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess, а также набор правил сборки, которая содержит закрытый элемент, к которому необходимо получить доступ.
Так как учитывается набор правил закрытого элемента, код с частичным доверием, которому было предоставлено разрешение ReflectionPermissionFlag.RestrictedMemberAccess, не может повысить свои привилегии путем выполнения закрытых элементов доверенных сборок.
Как и с любым другим выпущенным кодом, выполнение этого динамического метода нуждается в тех разрешениях, которые были востребованы методами, используемыми динамическим методом.
Системная сборка, содержащая анонимно размещенные динамические методы, использует модель прозрачности SecurityRuleSet.Level1, представляющую собой модель прозрачности, которая использовалась в платформе .NET Framework до версии .NET Framework 4.
Дополнительные сведения см. в описании класса DynamicMethod.
Создание анонимно размещенных динамических методов из кода с частичным доверием
Рассмотрите условия, при которых сборка с интернет-разрешениями может создать анонимно размещенный динамический метод и запустить его:
В динамическом методе используются только открытые типы и элементы. Если его набор правил содержит ReflectionPermissionFlag.RestrictedMemberAccess, могут использоваться закрытые типы и элементы любой сборки, набор правил которой равен набору правил выпустившей сборки или являться его поднабором.
Разрешения, которые требуются всеми типами и элементами, используемыми динамическим методом, включены в набор правил сборки с частичным доверием.
![]() |
---|
Динамические методы не поддерживают символы отладки. |
Динамические методы, связанные с текущими сборками
Чтобы связать динамический метод с типом или модулем в существующей сборке, используйте любой конструктор DynamicMethod, который указывает связанный тип или модуль. Разрешения, которые требуются для вызова этих конструкторов, могут быть разными, так как сопоставление динамического метода с существующим типом и модулем предоставляет динамическому методу доступ к закрытым типом и элементам:
Динамический метод, сопоставленный с типом, имеет доступ ко всем элементам этого типа, даже закрытым элементам, а также ко всем внутренним типам и элементам в сборке, содержащей связанный тип.
Динамический метод, связанный с модулем, имеет доступ ко всем типам и элементам internal (Friend в Visual Basic, assembly в метаданных среды CLR) в модуле.
Кроме того, можно использовать конструктор, который определяет возможность пропуска проверок видимости, выполняемых JIT-компилятором. Это предоставляет для динамического метода доступ ко всем типам и элементам во всех сборках независимо от уровня доступа.
Разрешения, требуемые конструктором, зависят от уровня доступа, который будет предоставлен динамическому методу:
Если этот метод использует только открытые типы и элементы и он сопоставлен с пользовательским типом или модулем, то никаких разрешений не требуется.
Если отменить проверки видимости, выполняемые JIT-компилятором, конструктор требует разрешение ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess.
Если сопоставить динамический метод с другим типом, даже с другим типом из пользовательской сборки, конструктор нуждается в разрешении ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess и в разрешении SecurityPermission с флагом SecurityPermissionFlag.ControlEvidence.
Если сопоставить динамический метод с типом или модулем в другой сборке, конструктор нуждается в разрешении ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess и наборе разрешений сборки, которая содержит другой модуль. То есть стек вызовов должен содержать все разрешения в наборе правил целевого модуля, а также ReflectionPermissionFlag.RestrictedMemberAccess.
Примечание
В целях обратной совместимости, если запрос на получение целевого набора правил и ReflectionPermissionFlag.RestrictedMemberAccess завершается со сбоем, конструктор запрашивает SecurityPermission с флагом SecurityPermissionFlag.ControlEvidence.
Несмотря на то, что элементы в этом списке описаны в терминах набора правил выпускающей сборки, помните, что требования предъявляются к полному стеку вызовов, включая границы домена приложения.
Дополнительные сведения см. в описании класса DynamicMethod.
Создание динамических методов из кода с частичным доверием
![]() |
---|
Рекомендуемый способ создания динамических методов из кода с частичным доверием — это использование анонимно размещенных методов. |
Рассмотрите условия, при которых сборка с интернет-разрешениями может создать и запустить динамический метод:
Или динамический метод связан с выпустившем его модулем или типом, или в его наборе правил содержится ReflectionPermissionFlag.RestrictedMemberAccess, и этот набор связан с модулем в сборке, набор правил которой равен набору правил выпустившей сборки или является его поднабором.
В динамическом методе используются только открытые типы и элементы. Если его набор правил содержит ReflectionPermissionFlag.RestrictedMemberAccess, а сам набор связан с модулем в сборке, набор правил которой равен набору правил выпустившей сборки или является его поднабором, в связанном модуле могут использоваться типы и элементы, отмеченные как internal (Friend в Visual Basic, assembly в метаданных среды CLR).
Разрешения, требуемые всеми типами и элементами, которые используются динамическим методом, включены в набор правил сборки с частичным доверием.
Динамический метод не пропускает проверки видимости, выполняемые JIT-компилятором.
![]() |
---|
Динамические методы не поддерживают символы отладки. |
Сведения о версии
Начиная с .NET Framework 4, политика безопасности на уровне компьютера больше не используется и механизмом обеспечения безопасности по умолчанию становится прозрачность безопасности. См. раздел Изменения системы безопасности в платформе .NET Framework 4.
Начиная с версии .NET Framework 2.0 с пакетом обновления 1 (SP1), разрешение ReflectionPermission с флагом ReflectionPermissionFlag.ReflectionEmit уже не требуется при выпуске динамических сборок и динамических методов. Этот флаг необходим в боле ранних версиях .NET Framework.
![]() |
---|
Разрешение ReflectionPermission с флагом ReflectionPermissionFlag.ReflectionEmit содержится по умолчанию в именованных наборах разрешений FullTrust и LocalIntranet, однако отсутствует в наборе разрешений Internet.Поэтому в более ранних версиях платформы .NET Framework библиотека может использоваться с интернет-разрешениями только в том, случае, если она запускает метод Assert для ReflectionEmit.Подобные библиотеки нуждаются в тщательном обеспечении безопасности, так как ошибки в коде могут привести к серьезным брешам в системе безопасности.В платформе .NET Framework 2.0 с пакетом обновления 1 (SP1) код может быть выпущен в сценариях частичного доверия без создания любых требований к безопасности, так как создание кода по существу не является привилегированной операцией.То есть созданный код имеет не больше разрешений, чем выпустившая его сборка.Это позволяет библиотекам выпускать код, прозрачный для безопасности, и устраняет необходимость в подтверждении ReflectionEmit, что упрощает задачу написания безопасной библиотеки. |
Кроме того, в платформе .NET Framework 2.0 с пакетом обновления 1 (SP1) представлен флаг ReflectionPermissionFlag.RestrictedMemberAccess для доступа к закрытым типам и элементам из динамических методов с частичным доверием. В более ранних версиях .NET Framework для динамических методов, получающих доступ к закрытым типам и элементам, требуется флаг ReflectionPermissionFlag.MemberAccess; это разрешение никогда не должно предоставляться коду с частичным доверием.
Наконец, в платформе .NET Framework 2.0 с пакетом обновления 1 (SP1) представлены анонимно размещенные методы.
Получение сведений о типах и элементах
Начиная с .NET Framework 2.0, для получения сведений о закрытых типах и элементах никаких разрешений не требуется. Отражение используется для получение сведений, необходимых для выпуска динамических методов. Например, объекты MethodInfo используются для выпуска вызовов метода. В более ранних версиях .NET Framework требовалось разрешение ReflectionPermission с флагом ReflectionPermissionFlag.TypeInformation. Дополнительные сведения см. в разделе Соображения о безопасности для отражения.
См. также
Основные понятия
Соображения о безопасности для отражения