Problemas de segurança na emissão de reflexãoSecurity Issues in Reflection Emit

O .NET Framework fornece três maneiras de emitir a MSIL (Microsoft Intermediate Language), cada uma com seus próprios problemas de segurança:The .NET Framework provides three ways to emit Microsoft intermediate language (MSIL), each with its own security issues:

Independentemente do modo como você gerar código dinâmico, a execução do código gerado requer que todas as permissões necessárias para os tipos e métodos que o código gerado usa.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.

Observação

As permissões que são necessárias para refletir o código e emitir o código foram alteradas com versões posteriores do .NET Framework.The permissions that are required for reflecting on code and emitting code have changed with succeeding releases of the .NET Framework. Consulte Informações de versão posteriormente neste tópico.See Version Information, later in this topic.

Assemblies DinâmicosDynamic Assemblies

Os assemblies dinâmicos são criados usando as sobrecargas do método AppDomain.DefineDynamicAssembly.Dynamic assemblies are created by using overloads of the AppDomain.DefineDynamicAssembly method. A maioria das sobrecargas desse método foi preterida no .NET Framework 4 devido à eliminação da política de segurança de todo o computador.Most overloads of this method are deprecated in the .NET Framework 4, because of the elimination of machine-wide security policy. (Veja alterações de segurança.) As sobrecargas restantes podem ser executadas por qualquer código, independentemente do nível de confiança.(See Security Changes.) The remaining overloads can be executed by any code, regardless of trust level. Essas sobrecargas se enquadram em dois grupos: aquelas que especificam uma lista de atributos a ser aplicada ao assembly dinâmico quando ele é criado e aquelas que não.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. Se você não especificar o modelo de transparência do assembly, aplicando o atributo SecurityRulesAttribute quando criá-lo, o modelo de transparência será herdado do assembly emissor.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.

Observação

Os atributos aplicados ao assembly dinâmico após ele ser criado, usando o método SetCustomAttribute, não entram em vigor até que o assembly tenha sido salvo no disco e carregado na memória novamente.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.

O código em um assembly dinâmico pode acessar membros e tipos visíveis em outros assemblies.Code in a dynamic assembly can access visible types and members in other assemblies.

Observação

Os assemblies dinâmicos não usam os sinalizadores ReflectionPermissionFlag.MemberAccess e ReflectionPermissionFlag.RestrictedMemberAccess que permitem que os métodos dinâmicos acessem tipos e membros não públicos.Dynamic assemblies do not use the ReflectionPermissionFlag.MemberAccess and ReflectionPermissionFlag.RestrictedMemberAccess flags that allow dynamic methods to access nonpublic types and members.

Os assemblies dinâmicos transitórios são criados na memória e nunca salvos no disco, portanto, eles não exigem nenhuma permissão de acesso ao arquivo.Transient dynamic assemblies are created in memory and never saved to disk, so they require no file access permissions. Salvar um assembly dinâmico em disco requer FileIOPermission com os sinalizadores adequados.Saving a dynamic assembly to disk requires FileIOPermission with the appropriate flags.

Gerando assemblies dinâmicos do código parcialmente confiávelGenerating Dynamic Assemblies from Partially Trusted Code

Considere as condições em que um assembly com permissões de Internet pode gerar um assembly dinâmico transitório e executar seu código:Consider the conditions in which an assembly with Internet permissions can generate a transient dynamic assembly and execute its code:

  • O assembly dinâmico usa apenas tipos e membros públicos de outros assemblies.The dynamic assembly uses only public types and members of other assemblies.

  • As permissões exigidas por esses tipos e membros são incluídas no conjunto de concessão do assembly parcialmente confiável.The permissions demanded by those types and members are included in the grant set of the partially trusted assembly.

  • O assembly não é salvo no disco.The assembly is not saved to disk.

  • Os símbolos de depuração não são gerados.Debug symbols are not generated. (Os conjuntos de permissões Internet e LocalIntranet não incluem as permissões necessárias.)(Internet and LocalIntranet permission sets do not include the necessary permissions.)

Métodos Dinâmicos Hospedados AnonimamenteAnonymously Hosted Dynamic Methods

Os métodos dinâmicos hospedados anonimamente são criados usando os dois construtores DynamicMethod que não especificam um módulo ou tipo associado, DynamicMethod(String, Type, Type[]) e 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). Esses construtores colocam os métodos dinâmicos em um assembly transparente de segurança totalmente confiável fornecido pelo sistema.These constructors place the dynamic methods in a system-provided, fully trusted, security-transparent assembly. Não é necessária nenhuma permissão para usar esses construtores ou para emitir o código para os métodos dinâmicos.No permissions are required to use these constructors or to emit code for the dynamic methods.

Em vez disso, quando um método dinâmico hospedado anonimamente é criado, a pilha de chamadas é capturada.Instead, when an anonymously hosted dynamic method is created, the call stack is captured. Quando o método é construído, as demandas de segurança são feitas em relação à pilha de chamadas capturada.When the method is constructed, security demands are made against the captured call stack.

Observação

Conceitualmente, as demandas são feitas durante a construção do método.Conceptually, demands are made during the construction of the method. Ou seja, as demandas podem ser feitas conforme cada instrução MSIL é emitida.That is, demands could be made as each MSIL instruction is emitted. Na implementação atual, todas as solicitações são feitas quando o método DynamicMethod.CreateDelegate é chamado ou quando o compilador JIT (Just-In-Time) é invocado, se o método for invocado sem chamar 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.

Se o domínio do aplicativo permitir isso, os métodos dinâmicos hospedados anonimamente podem ignorar as verificações de visibilidade JIT, sujeitos à seguinte restrição: os tipos e membros não públicos acessados por um método dinâmico hospedado anonimamente devem estar em assemblies cujos conjuntos de concessões sejam iguais ao, ou subconjuntos de, conjunto de concessões da pilha de chamadas emissora.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. Essa capacidade restrita de ignorar as verificações de visibilidade JIT é habilitada se o domínio do aplicativo concede ReflectionPermission com o sinalizador ReflectionPermissionFlag.RestrictedMemberAccess.This restricted ability to skip JIT visibility checks is enabled if the application domain grants ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag.

  • Se o método usar apenas membros e tipos públicos, não serão necessárias permissões durante a construção.If your method uses only public types and members, no permissions are required during construction.

  • Se você especificar que as verificações de visibilidade JIT devem ser ignoradas, a solicitação feita quando o método é construído incluirá ReflectionPermission com o sinalizador ReflectionPermissionFlag.RestrictedMemberAccess e o conjunto de concessões do assembly que contém o membro não público sendo acessado.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.

Como o conjunto de concessões do membro não público é considerado, o código parcialmente confiável que recebeu ReflectionPermissionFlag.RestrictedMemberAccess não pode elevar seus privilégios executando membros não públicos de assemblies confiáveis.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.

Como com qualquer outro código emitido, executar o método dinâmico requer as permissões que são exigidas pelos métodos que o método dinâmico usa.As with any other emitted code, executing the dynamic method requires whatever permissions are demanded by the methods the dynamic method uses.

O assembly do sistema que hospeda métodos dinâmicos hospedados anonimamente usa o modelo de transparência SecurityRuleSet.Level1, que é o modelo de transparência que era usado no .NET Framework antes do .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.

Para obter mais informações, consulte a classe DynamicMethod.For more information, see the DynamicMethod class.

Gerando métodos dinâmicos hospedados anonimamente do código parcialmente confiávelGenerating Anonymously Hosted Dynamic Methods from Partially Trusted Code

Considere as condições em que um assembly com permissões de Internet pode gerar um assembly dinâmico hospedado anonimamente e executá-lo:Consider the conditions in which an assembly with Internet permissions can generate an anonymously hosted dynamic method and execute it:

  • O método dinâmico usa apenas tipos e membros públicos.The dynamic method uses only public types and members. Se o seu conjunto de concessões inclui ReflectionPermissionFlag.RestrictedMemberAccess, ele pode usar membros e tipos não públicos de qualquer assembly cujo conjunto de concessões seja igual ao, ou um subconjunto do, conjunto de concessões do assembly emissor.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.

  • As permissões exigidas por todos os tipos e membros usados pelo método dinâmico são incluídas no conjunto de concessões do assembly parcialmente confiável.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.

Observação

Os métodos dinâmicos não têm suporte para símbolos de depuração.Dynamic methods do not support debug symbols.

Métodos Dinâmicos Associados a Assemblies ExistentesDynamic Methods Associated with Existing Assemblies

Para associar um método dinâmico a um tipo ou um módulo em um assembly existente, use qualquer um dos construtores DynamicMethod que especificam o módulo ou tipo associado.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. As permissões necessárias para chamar esses construtores variam, pois associar um método dinâmico a um módulo ou tipo existente fornece ao método dinâmico o acesso aos membros e tipos não públicos: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:

  • Um método dinâmico associado um tipo tem acesso a todos os membros desse tipo, mesmo membros privados e a todos os tipos e membros internos no assembly que contém o tipo associado.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.

  • Um método dinâmico que está associado um módulo tem acesso a todos os tipos e membros internal (Friend no Visual Basic, assembly nos metadados do Common Language Runtime) no módulo.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.

Além disso, você pode usar um construtor que especifica a capacidade de ignorar as verificações de visibilidade do compilador JIT.In addition, you can use a constructor that specifies the ability to skip the visibility checks of the JIT compiler. Fazer isso concede ao seu método dinâmico o acesso a todos os tipos e membros em todos os assemblies, independentemente do nível de acesso.Doing so gives your dynamic method access to all types and members in all assemblies, regardless of access level.

As permissões exigidas pelo construtor dependem de quanto acesso você decide conceder ao seu método dinâmico:The permissions demanded by the constructor depend on how much access you decide to give your dynamic method:

Embora os itens nessa lista estejam descritos em termos do conjunto de concessões do assembly emissor, lembre-se de que as exigências são feitas em relação à pilha de chamadas completa, incluindo o limite de domínio do aplicativo.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.

Para obter mais informações, consulte a classe DynamicMethod.For more information, see the DynamicMethod class.

Gerando métodos dinâmicos do código parcialmente confiávelGenerating Dynamic Methods from Partially Trusted Code

Observação

A maneira recomendada para gerar métodos dinâmicos do código parcialmente confiável é usar métodos dinâmicos hospedados anonimamente.The recommended way to generate dynamic methods from partially trusted code is to use anonymously hosted dynamic methods.

Considere as condições em que um assembly com permissões de Internet pode gerar um método dinâmico e executá-lo:Consider the conditions in which an assembly with Internet permissions can generate a dynamic method and execute it:

  • O método dinâmico é associado ao módulo ou tipo que o emite ou seu conjunto de concessões inclui ReflectionPermissionFlag.RestrictedMemberAccess e ele é associado a um módulo em um assembly cujo conjunto de concessões é igual ao ou um subconjunto do, conjunto de concessões do assembly emissor.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.

  • O método dinâmico usa apenas tipos e membros públicos.The dynamic method uses only public types and members. Se seu conjunto de concessões incluir ReflectionPermissionFlag.RestrictedMemberAccess e estiver associado a um módulo em um assembly cujo conjunto de concessões é igual ao ou um subconjunto do, conjunto de concessões do assembly emissor, ele poderá usar tipos e membros marcados com internal (Friend no Visual Basic, assembly nos metadados do Common Language Runtime) no módulo associado.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.

  • As permissões exigidas por todos os tipos e membros usados pelo método dinâmico são incluídas no conjunto de concessões do assembly parcialmente confiável.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.

  • O método dinâmico não ignora as verificações de visibilidade JIT.The dynamic method does not skip JIT visibility checks.

Observação

Os métodos dinâmicos não têm suporte para símbolos de depuração.Dynamic methods do not support debug symbols.

Informações sobre versãoVersion Information

Do .NET Framework 4 em diante, a política de segurança de todo computador é eliminada e a transparência de segurança se torna o mecanismo de imposição padrão.Starting with the .NET Framework 4, machine-wide security policy is eliminated and security transparency becomes the default enforcement mechanism. Consulte Alterações de segurança.See Security Changes.

Desde o .NET Framework 2.0 Service Pack 1, ReflectionPermission com o sinalizador ReflectionPermissionFlag.ReflectionEmit não é mais necessário ao emitir métodos dinâmicos e assemblies dinâmicos.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. Esse sinalizador é exigido em todas as versões anteriores do .NET Framework.This flag is required in all earlier versions of the .NET Framework.

Observação

ReflectionPermission com o sinalizador ReflectionPermissionFlag.ReflectionEmit é incluído por padrão nos conjuntos de permissões denominados FullTrust e LocalIntranet, mas não no conjunto de permissões 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. Portanto, em versões anteriores do .NET Framework, uma biblioteca poderá ser usada com permissões de Internet somente se ela executar um Assert para 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. Tais bibliotecas exigem uma análise atenta da segurança, pois erros de código poderiam resultar em falhas de segurança.Such libraries require careful security review because coding errors could result in security holes. O .NET Framework 2.0 SP1 permite que o código seja emitido em cenários de confiança parcial sem emitir qualquer demanda de segurança, pois a geração de código não é uma operação inerentemente privilegiada.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. Ou seja, o código gerado não tem mais permissões que o assembly que o emite.That is, the generated code has no more permissions than the assembly that emits it. Isso permite que as bibliotecas que emitem código tenham a segurança transparente e remove a necessidade de declarar ReflectionEmit, o que simplifica a tarefa de escrever uma biblioteca de segurança.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.

Além disso, o .NET Framework 2.0 SP1 introduz o sinalizador ReflectionPermissionFlag.RestrictedMemberAccess para acessar membros e tipos não públicos de métodos dinâmicos parcialmente confiáveis.In addition, the .NET Framework 2.0 SP1 introduces the ReflectionPermissionFlag.RestrictedMemberAccess flag for accessing nonpublic types and members from partially trusted dynamic methods. Versões anteriores do .NET Framework exigem o sinalizador ReflectionPermissionFlag.MemberAccess para os métodos dinâmicos que acessam os membros e tipos não públicos. Essa é uma permissão que não deve ser concedida nunca ao código parcialmente confiável.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.

Por fim, o .NET Framework 2.0 SP1 introduz os métodos hospedados anonimamente.Finally, the .NET Framework 2.0 SP1 introduces anonymously hosted methods.

Obtendo informações sobre tipos e membrosObtaining Information on Types and Members

A partir do .NET Framework 2.0, não é necessária nenhuma permissão para obter informações sobre membros e tipos não públicos.Starting with the .NET Framework 2.0, no permissions are required to obtain information about nonpublic types and members. A reflexão é usada para obter as informações necessárias para emitir métodos dinâmicos.Reflection is used to obtain information needed to emit dynamic methods. Por exemplo, os objetos MethodInfo são usados para emitir chamadas de método.For example, MethodInfo objects are used to emit method calls. As versões anteriores do .NET Framework exigem ReflectionPermission com o sinalizador ReflectionPermissionFlag.TypeInformation.Earlier versions of the .NET Framework require ReflectionPermission with the ReflectionPermissionFlag.TypeInformation flag. Para obter mais informações, consulte Security Considerations for Reflection (Considerações sobre segurança relacionadas à reflexão).For more information, see Security Considerations for Reflection.

Confira tambémSee also