Вопросы безопасности в порождаемом отражении
Обновлен: Ноябрь 2007
.NET Framework предоставляет три способа выпуска MSIL, каждый из которых имеет собственные вопросы безопасности:
Динамические сборки
Анонимно размещенные динамические методы
Динамические методы, связанные с текущими сборками
Независимо от способа создания динамического кода, для выполнения созданного кода необходимы все разрешения, которые требуется типами и методами, используемыми в этом коде.
Примечание. |
---|
Разрешения, необходимые для отражения кода и выпуска кода, изменились с последующими выпусками .NET Framework. См. подраздел Сведения о версии, приведенный ниже. |
Динамические сборки
Динамические сборки создаются с помощью перегрузок метода AppDomain.DefineDynamicAssembly. Необходимые разрешения зависят от используемой перегрузки. Перегрузки, предоставляющие, например, свидетельства, нуждаются в разрешении SecurityPermission с флагом SecurityPermissionFlag.ControlEvidence. В некоторых перегрузках разрешений не требуется, поэтому они могут быть вызваны из кода, имеющего только интернет-разрешения.
Код в динамической сборке может получить доступ к видимым типам и элементам в других сборках.
Примечание. |
---|
Динамические сборки не используют флаги ReflectionPermissionFlag.MemberAccess и ReflectionPermissionFlag.RestrictedMemberAccess, с помощью которых динамические методы могут получать доступ к закрытым типам и элементам. |
При создании кода с символами отладки требуется разрешение ReflectionPermission с флагом ReflectionPermissionFlag.ReflectionEmit.
Временные динамические сборки создаются в памяти и никогда не сохраняются на диске, поэтому для них не требуется разрешения на доступ к файлам. Для сохранения динамической сборки на диск требуется разрешение FileIOPermission с соответствующими флагами.
Создание динамических сборок из кода с частичным доверием
Рассмотрите условия, при которых сборка с интернет-разрешениями может создать временную динамическую сборку и выполнить код:
Динамическая сборка использует только открытые типы и элементы других сборок.
Разрешения, необходимые для этих типов и элементов, включаются в набор прав сборки с частичным доверием.
Перегрузка метода DefineDynamicAssembly, используемая для создания динамической сборки, не нуждается в специальных разрешениях (то есть, свидетельство не предоставляется и т. д.).
Сборка не сохраняется на диск.
Символы отладки не создаются. (Наборы разрешений Internet и LocalIntranet не содержат флаг ReflectionPermissionFlag.ReflectionEmit.)
Создание разрешений для динамических сборок
В следующем списке "источником" считается сборка, создающая динамическую сборку.
Источник, имеющий разрешение SecurityPermission с флагом SecurityPermissionFlag.ControlEvidence может предоставить свидетельство для созданного кода. Это свидетельство заносится в политику для определения предоставленных разрешений.
Источник может предоставить пустое свидетельство; в этом случае сборка получает набор разрешений источника. Это гарантирует, что созданный код не обладает большими разрешениями, чем источник.
При предоставлении наборов разрешений с флагами SecurityAction.RequestMinimum, SecurityAction.RequestOptional или SecurityAction.RequestRefuse эти наборы разрешений не используются до тех пор, пока сборка не будет сохранена на диск, а затем загружена с диска.
После сохранения динамической сборки на диск эта сборка обрабатывается, как и любая другая сборка, загруженная с диска.
Всегда проверяется код, созданный источниками с частичным доверием. В частности, во время выполнения всегда проверяется код, который не имеет разрешения SecurityPermission с флагом SecurityPermissionFlag.SkipVerification. Источники с полным доверием могут либо пропускать проверку, либо требовать проверки созданного кода.
Анонимно размещенные динамические методы
Анонимно размещенные динамические методы созданы с помощью двух конструкторов DynamicMethod, которые не указывают связанный тип или модуль: DynamicMethod(String, Type, array<Type[]) и DynamicMethod(String, Type, array<Type[], Boolean). Эти конструкторы размещают динамические методы в сборке, которая предоставляется системой, имеет полное доверие и является прозрачной для системы безопасности. Чтобы использовать эти конструкторы или выпускать код для динамических методов, никаких разрешений не требуется.
Вместо этого при создании анонимно размещенных динамических методов перехватывается стек вызовов. При создании метода требования безопасности предъявляются к перехваченному стеку вызовов.
Примечание. |
---|
Концептуально требования предъявляются во время создания метода. То есть требования могут предъявляться при выпуске каждой инструкции MSIL. В текущей реализации все требования предъявляются при вызове метода DynamicMethod.CreateDelegate или при вызове JIT-компилятора, если метод вызывается без обращения к методу CreateDelegate. |
Анонимно размещенные динамические методы могут пропускать проверки видимости, выполняемые JIT-компилятором, и подлежат следующему ограничению: закрытые типы и элементы, к которым получает доступ анонимно размещенные динамические методы, должны находиться в сборках, наборы прав которых равны набору прав выпускающего стека вызовов или являются его поднаборами. Эта ограниченная возможность пропуска проверок видимости, выполняемых JIT-компилятором, нуждается в разрешении ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess.
Если в методе используются только открытые типы и элементы, во время создания никаких разрешений не требуется.
Если отменить проверки видимости, выполняемые JIT-компилятором, требование, предъявляемое при создании метода, содержит разрешение ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess, а также набор правил сборки, которая содержит закрытый элемент, к которому необходимо получить доступ.
Так как учитывается набор правил закрытого элемента, код с частичным доверием, которому было предоставлено разрешение ReflectionPermissionFlag.RestrictedMemberAccess, не может повысить свои привилегии путем выполнения закрытых элементов доверенных сборок.
Как и с любым другим выпущенным кодом, выполнение этого динамического метода нуждается в тех разрешениях, которые были востребованы методами, используемыми динамическим методом.
Дополнительные сведения см. в описании класса 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 версия 2.0, с пакетом обновления 1, разрешение 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, версия 3.5. Дополнительные сведения см. в разделе .Архитектура платформы .NET Framework версии 3.5.
Получение сведений о типах и элементах
Начиная с .NET Framework 2.0, для получения сведений о закрытых типах и элементах никаких разрешений не требуется. Отражение используется для получение сведений, необходимых для выпуска динамических методов. Например, объекты MethodInfo используются для выпуска вызовов метода. В более ранних версиях .NET Framework требовалось разрешение ReflectionPermission с флагом ReflectionPermissionFlag.TypeInformation. Дополнительные сведения см. в разделе Соображения о безопасности для отражения.
См. также
Основные понятия
Соображения о безопасности для отражения