Noções básicas da segurança de acesso do códigoCode Access Security Basics

Cuidado

CAS (segurança de acesso a código) e código parcialmente confiávelCode Access Security (CAS) and Partially Trusted Code

O .NET Framework fornece um mecanismo para a imposição de níveis variáveis de confiança em códigos diferentes em execução no mesmo aplicativo chamado CAS (Segurança de Acesso do Código).The .NET Framework provides a mechanism for the enforcement of varying levels of trust on different code running in the same application called Code Access Security (CAS).

Não há suporte para CAS no .NET Core, no .NET 5 ou em versões posteriores. Não há suporte para CAS em versões do C# posteriores a 7,0.CAS is not supported in .NET Core, .NET 5, or later versions. CAS is not supported by versions of C# later than 7.0.

As CAS no .NET Framework não devem ser usadas como um mecanismo para impor limites de segurança com base na origem do código ou em outros aspectos de identidade.CAS in .NET Framework should not be used as a mechanism for enforcing security boundaries based on code origination or other identity aspects. Não há suporte para CAS e código de Security-Transparent como um limite de segurança com código parcialmente confiável, especialmente código de origem desconhecida.CAS and Security-Transparent Code are not supported as a security boundary with partially trusted code, especially code of unknown origin. Não aconselhamos carregar e executar códigos de origens desconhecidas sem a adoção de medidas de segurança alternativas no local.We advise against loading and executing code of unknown origins without putting alternative security measures in place. .NET Framework não emitirá patches de segurança para quaisquer explorações de elevação de privilégio que possam ser descobertas na área restrita do CAS..NET Framework will not issue security patches for any elevation-of-privilege exploits that might be discovered against the CAS sandbox.

Essa política é aplicável à todas as versões do .NET Framework, mas não é aplicável ao .NET Framework incluído no Silverlight.This policy applies to all versions of .NET Framework, but does not apply to the .NET Framework included in Silverlight.

Todos os aplicativos que se destinam à Common Language Runtime (ou seja, todos os aplicativos gerenciados) devem interagir com o sistema de segurança do tempo de execução.Every application that targets the common language runtime (that is, every managed application) must interact with the runtime's security system. Quando um aplicativo gerenciado é carregado, seu host o concede automaticamente a ele um conjunto de permissões.When a managed application is loaded, its host automatically grants it a set of permissions. Essas permissões são determinadas pelas configurações de segurança local do host ou pela área restrita em que o aplicativo está.These permissions are determined by the host's local security settings or by the sandbox the application is in. Dependendo dessas permissões, o aplicativo é executado corretamente ou gera uma exceção de segurança.Depending on these permissions, the application either runs properly or generates a security exception.

O host padrão para aplicativos de área de trabalho permite que o código seja executado em confiança total.The default host for desktop applications allows code to run in full trust. Portanto, se o seu aplicativo for direcionado para a área de trabalho, ele terá um conjunto de permissões irrestrito.Therefore, if your application targets the desktop, it has an unrestricted permission set. Outros hosts ou áreas restritas fornecem um conjunto de permissões limitado para aplicativos.Other hosts or sandboxes provide a limited permission set for applications. Como o conjunto de permissões pode ser alterado de host para host, você deve projetar seu aplicativo para usar apenas as permissões que o host de destino permite.Because the permission set can change from host to host, you must design your application to use only the permissions that your target host allows.

Você deve estar familiarizado com os seguintes conceitos de segurança de acesso ao código para escrever aplicativos efetivos direcionados ao Common Language Runtime:You must be familiar with the following code access security concepts in order to write effective applications that target the common language runtime:

  • Código de tipo seguro: o código de tipo seguro é o código que acessa tipos somente de maneiras bem definidas e permitidas.Type-safe code: Type-safe code is code that accesses types only in well-defined, allowable ways. Por exemplo, considerando uma referência de objeto válida, o código de tipo seguro pode acessar a memória em deslocamentos fixos que correspondem aos membros reais do campo.For example, given a valid object reference, type-safe code can access memory at fixed offsets that correspond to actual field members. Se o código acessar a memória em deslocamentos arbitrários fora do intervalo de memória que pertence aos campos expostos publicamente do objeto, ele não será de tipo seguro.If the code accesses memory at arbitrary offsets outside the range of memory that belongs to that object's publicly exposed fields, it is not type-safe. Para permitir que o código se beneficie da segurança de acesso ao código, você deve usar um compilador que gera um código de tipo seguro com verificação.To enable code to benefit from code access security, you must use a compiler that generates verifiably type-safe code. Para obter mais informações, consulte a seção escrevendo código com segurança de tipo verificável mais adiante neste tópico.For more information, see the Writing Verifiably Type-Safe Code section later in this topic.

  • Sintaxe imperativa e declarativa: o código que tem como alvo o Common Language Runtime pode interagir com o sistema de segurança solicitando permissões, exigindo que os chamadores tenham permissões especificadas e substituindo determinadas configurações de segurança (dadas privilégios suficientes).Imperative and declarative syntax: Code that targets the common language runtime can interact with the security system by requesting permissions, demanding that callers have specified permissions, and overriding certain security settings (given enough privileges). Você usa duas formas de sintaxe para interagir de forma programática com o .NET Framework sistema de segurança: sintaxe declarativa e sintaxe imperativa.You use two forms of syntax to programmatically interact with the .NET Framework security system: declarative syntax and imperative syntax. Chamadas declarativas são executadas usando atributos; as chamadas imperativas são executadas usando novas instâncias de classes dentro de seu código.Declarative calls are performed using attributes; imperative calls are performed using new instances of classes within your code. Algumas chamadas podem ser executadas apenas imperativamente, outras podem ser executadas apenas de forma declarativa e algumas chamadas podem ser executadas de qualquer maneira.Some calls can be performed only imperatively, others can be performed only declaratively, and some calls can be performed in either manner.

  • Bibliotecas de classes seguras: uma biblioteca de classes segura usa as demandas de segurança para garantir que os chamadores da biblioteca tenham permissão para acessar os recursos que a biblioteca expõe.Secure class libraries: A secure class library uses security demands to ensure that the library's callers have permission to access the resources that the library exposes. Por exemplo, uma biblioteca de classes segura pode ter um método para criar arquivos que exigem que seus chamadores tenham permissões para criar arquivos.For example, a secure class library might have a method for creating files that would demand that its callers have permissions to create files. O .NET Framework consiste em bibliotecas de classes seguras.The .NET Framework consists of secure class libraries. Você deve estar ciente das permissões necessárias para acessar qualquer biblioteca que seu código usa.You should be aware of the permissions required to access any library that your code uses. Para obter mais informações, consulte a seção usando bibliotecas de classes seguras mais adiante neste tópico.For more information, see the Using Secure Class Libraries section later in this topic.

  • Código Transparent: começando com o .NET Framework 4, além de identificar permissões específicas, você também deve determinar se o seu código deve ser executado como de segurança transparente.Transparent code: Starting with the .NET Framework 4, in addition to identifying specific permissions, you must also determine whether your code should run as security-transparent. O código de segurança transparente não pode chamar tipos ou membros que são identificados como segurança crítica.Security-transparent code cannot call types or members that are identified as security-critical. Essa regra se aplica a aplicativos de confiança total, bem como a aplicativos parcialmente confiáveis.This rule applies to full-trust applications as well as partially trusted applications. Para obter mais informações, consulte código de segurança transparente.For more information, see Security-Transparent Code.

Escrevendo um código fortemente tipado verificávelWriting Verifiably Type-Safe Code

A compilação JIT (just-in-time) executa um processo de verificação que examina o código e tenta determinar se o código é de tipo seguro.Just-in-time (JIT) compilation performs a verification process that examines code and tries to determine whether the code is type-safe. O código que é comprovado durante a verificação para ser digitado com segurança é chamado de código de tipo seguro verificável.Code that is proven during verification to be type-safe is called verifiably type-safe code. O código pode ser de tipo seguro, mas pode não ser verificável com segurança devido às limitações do processo de verificação ou do compilador.Code can be type-safe, yet might not be verifiably type-safe because of the limitations of the verification process or of the compiler. Nem todas as linguagens são de tipo seguro, e alguns compiladores de linguagem, como Microsoft Visual C++, não podem gerar código gerenciado com segurança de tipo verificável.Not all languages are type-safe, and some language compilers, such as Microsoft Visual C++, cannot generate verifiably type-safe managed code. Para determinar se o compilador de linguagem que você usa gera um código com segurança de tipo verificável, consulte a documentação do compilador.To determine whether the language compiler you use generates verifiably type-safe code, consult the compiler's documentation. Se você usar um compilador de linguagem que gera código de tipo seguro, apenas quando você evita determinadas construções de linguagem, convém usar a ferramenta PEVerify para determinar se o seu código é verificamente seguro.If you use a language compiler that generates verifiably type-safe code only when you avoid certain language constructs, you might want to use the PEVerify tool to determine whether your code is verifiably type-safe.

O código que não é verificável de tipo seguro pode tentar executar se a política de segurança permitir que o código ignore a verificação.Code that is not verifiably type-safe can attempt to execute if security policy allows the code to bypass verification. No entanto, como a segurança de tipo é uma parte essencial do mecanismo do tempo de execução para isolar assemblies, a segurança não poderá ser imposta de forma confiável se o código violar as regras de segurança de tipo.However, because type safety is an essential part of the runtime's mechanism for isolating assemblies, security cannot be reliably enforced if code violates the rules of type safety. Por padrão, o código que não é de tipo seguro pode ser executado somente se for originado do computador local.By default, code that is not type-safe is allowed to run only if it originates from the local computer. Portanto, o código móvel deve ser de tipo seguro.Therefore, mobile code should be type-safe.

Usando bibliotecas de classes segurasUsing Secure Class Libraries

Se seu código solicitar e receber as permissões exigidas pela biblioteca de classes, ele terá permissão para acessar a biblioteca e os recursos expostos pela biblioteca serão protegidos contra o acesso não autorizado.If your code requests and is granted the permissions required by the class library, it will be allowed to access the library and the resources that the library exposes will be protected from unauthorized access. Se o seu código não tiver as permissões apropriadas, ele não terá permissão para acessar a biblioteca de classes e o código mal-intencionado não poderá usar seu código para acessar indiretamente os recursos protegidos.If your code does not have the appropriate permissions, it will not be allowed to access the class library, and malicious code will not be able to use your code to indirectly access protected resources. Outro código que chama seu código também deve ter permissão para acessar a biblioteca.Other code that calls your code must also have permission to access the library. Caso contrário, seu código também será impedido de ser executado.If it does not, your code will be restricted from running as well.

A segurança de acesso ao código não elimina a possibilidade de erro humano em escrever código.Code access security does not eliminate the possibility of human error in writing code. No entanto, se seu aplicativo usar bibliotecas de classes seguras para acessar recursos protegidos, o risco de segurança para o código do aplicativo será reduzido, pois as bibliotecas de classes são rigorosamente fiscalizadas para possíveis problemas de segurança.However, if your application uses secure class libraries to access protected resources, the security risk for application code is decreased, because class libraries are closely scrutinized for potential security problems.

Segurança declarativaDeclarative Security

A sintaxe de segurança declarativa usa atributos para posicionar informações de segurança nos metadados do seu código.Declarative security syntax uses attributes to place security information into the metadata of your code. Os atributos podem ser colocados no nível de assembly, classe ou membro, para indicar o tipo de solicitação, demanda ou substituição que você deseja usar.Attributes can be placed at the assembly, class, or member level, to indicate the type of request, demand, or override you want to use. As solicitações são usadas em aplicativos direcionados à Common Language Runtime para informar o sistema de segurança de tempo de execução sobre as permissões que seu aplicativo precisa ou não deseja.Requests are used in applications that target the common language runtime to inform the runtime security system about the permissions that your application needs or does not want. As demandas e substituições são usadas em bibliotecas para ajudar a proteger recursos de chamadores ou para substituir o comportamento de segurança padrão.Demands and overrides are used in libraries to help protect resources from callers or to override default security behavior.

Observação

No .NET Framework 4, houve alterações importantes na .NET Framework modelo e terminologia de segurança.In the .NET Framework 4, there have been important changes to the .NET Framework security model and terminology. Para obter mais informações sobre essas alterações, consulte Security Changes.For more information about these changes, see Security Changes.

Para usar chamadas de segurança declarativas, você deve inicializar os dados de estado do objeto de permissão para que ele represente a forma específica de permissão necessária.In order to use declarative security calls, you must initialize the state data of the permission object so that it represents the particular form of permission you need. Cada permissão interna tem um atributo que é passado SecurityAction como uma enumeração para descrever o tipo de operação de segurança que você deseja executar.Every built-in permission has an attribute that is passed a SecurityAction enumeration to describe the type of security operation you want to perform. No entanto, as permissões também aceitam seus próprios parâmetros que são exclusivos para eles.However, permissions also accept their own parameters that are exclusive to them.

O fragmento de código a seguir mostra a sintaxe declarativa para solicitar que os chamadores de seu código tenham uma permissão personalizada chamada MyPermission .The following code fragment shows declarative syntax for requesting that your code's callers have a custom permission called MyPermission. Essa permissão é uma permissão personalizada hipotética e não existe no .NET Framework.This permission is a hypothetical custom permission and does not exist in the .NET Framework. Neste exemplo, a chamada declarativa é colocada diretamente antes da definição de classe, especificando que essa permissão seja aplicada ao nível de classe.In this example, the declarative call is placed directly before the class definition, specifying that this permission be applied to the class level. O atributo é passado uma estrutura SecurityAction. redemand para especificar que os chamadores devem ter essa permissão para serem executados.The attribute is passed a SecurityAction.Demand structure to specify that callers must have this permission in order to run.

<MyPermission(SecurityAction.Demand, Unrestricted = True)> Public Class MyClass1

   Public Sub New()
      'The constructor is protected by the security call.
   End Sub

   Public Sub MyMethod()
      'This method is protected by the security call.
   End Sub

   Public Sub YourMethod()
      'This method is protected by the security call.
   End Sub
End Class
[MyPermission(SecurityAction.Demand, Unrestricted = true)]
public class MyClass
{
   public MyClass()
   {
      //The constructor is protected by the security call.
   }

   public void MyMethod()
   {
      //This method is protected by the security call.
   }

   public void YourMethod()
   {
      //This method is protected by the security call.
   }
}

Segurança obrigatóriaImperative Security

A sintaxe de segurança imperativa emite uma chamada de segurança criando uma nova instância do objeto de permissão que você deseja invocar.Imperative security syntax issues a security call by creating a new instance of the permission object you want to invoke. Você pode usar a sintaxe imperativa para executar demandas e substituições, mas não solicitações.You can use imperative syntax to perform demands and overrides, but not requests.

Antes de fazer a chamada de segurança, você deve inicializar os dados de estado do objeto de permissão para que ele represente a forma específica da permissão necessária.Before you make the security call, you must initialize the state data of the permission object so that it represents the particular form of the permission you need. Por exemplo, ao criar um FileIOPermission objeto, você pode usar o construtor para inicializar o objeto FileIOPermission para que ele represente o acesso irrestrito a todos os arquivos ou nenhum acesso aos arquivos.For example, when creating a FileIOPermission object, you can use the constructor to initialize the FileIOPermission object so that it represents either unrestricted access to all files or no access to files. Ou, você pode usar um objeto FileIOPermission diferente, passando parâmetros que indicam o tipo de acesso que você deseja que o objeto represente (ou seja, leitura, acréscimo ou gravação) e quais arquivos você deseja que o objeto proteja.Or, you can use a different FileIOPermission object, passing parameters that indicate the type of access you want the object to represent (that is, read, append, or write) and what files you want the object to protect.

Além de usar a sintaxe de segurança imperativa para invocar um único objeto de segurança, você pode usá-lo para inicializar um grupo de permissões em um conjunto de permissões.In addition to using imperative security syntax to invoke a single security object, you can use it to initialize a group of permissions in a permission set. Por exemplo, essa técnica é a única maneira de executar chamadas Assert de forma confiável em várias permissões em um método.For example, this technique is the only way to reliably perform assert calls on multiple permissions in one method. Use as PermissionSet NamedPermissionSet classes e para criar um grupo de permissões e, em seguida, chame o método apropriado para invocar a chamada de segurança desejada.Use the PermissionSet and NamedPermissionSet classes to create a group of permissions and then call the appropriate method to invoke the desired security call.

Você pode usar a sintaxe imperativa para executar demandas e substituições, mas não solicitações.You can use imperative syntax to perform demands and overrides, but not requests. Você pode usar a sintaxe imperativa para demandas e substituições em vez de sintaxe declarativa quando as informações necessárias para inicializar o estado de permissão se tornarem conhecidas somente no tempo de execução.You might use imperative syntax for demands and overrides instead of declarative syntax when information that you need in order to initialize the permission state becomes known only at run time. Por exemplo, se você quiser garantir que os chamadores tenham permissão para ler um determinado arquivo, mas não souber o nome desse arquivo até o tempo de execução, use uma demanda imperativa.For example, if you want to ensure that callers have permission to read a certain file, but you do not know the name of that file until run time, use an imperative demand. Você também pode optar por usar verificações imperativas em vez de verificações declarativas quando precisar determinar em tempo de execução se uma condição mantiver e, com base no resultado do teste, fazer uma demanda de segurança (ou não).You might also choose to use imperative checks instead of declarative checks when you need to determine at run time whether a condition holds and, based on the result of the test, make a security demand (or not).

O fragmento de código a seguir mostra a sintaxe imperativa para solicitar que os chamadores de seu código tenham uma permissão personalizada chamada MyPermission .The following code fragment shows imperative syntax for requesting that your code's callers have a custom permission called MyPermission. Essa permissão é uma permissão personalizada hipotética e não existe no .NET Framework.This permission is a hypothetical custom permission and does not exist in the .NET Framework. Uma nova instância do MyPermission é criada no MyMethod , protegendo apenas esse método com a chamada de segurança.A new instance of MyPermission is created in MyMethod, guarding only this method with the security call.

Public Class MyClass1

   Public Sub New()

   End Sub

   Public Sub MyMethod()
      'MyPermission is demanded using imperative syntax.
      Dim Perm As New MyPermission()
      Perm.Demand()
      'This method is protected by the security call.
   End Sub

   Public Sub YourMethod()
      'YourMethod 'This method is not protected by the security call.
   End Sub
End Class
public class MyClass {
   public MyClass(){

   }

   public void MyMethod() {
       //MyPermission is demanded using imperative syntax.
       MyPermission Perm = new MyPermission();
       Perm.Demand();
       //This method is protected by the security call.
   }

   public void YourMethod() {
       //This method is not protected by the security call.
   }
}

Usando classes de wrapper gerenciadasUsing Managed Wrapper Classes

A maioria dos aplicativos e componentes (exceto bibliotecas seguras) não deve chamar diretamente o código não gerenciado.Most applications and components (except secure libraries) should not directly call unmanaged code. Há várias razões para isso.There are several reasons for this. Se o código chamar o código não gerenciado diretamente, ele não poderá ser executado em muitas circunstâncias porque o código deve receber um alto nível de confiança para chamar o código nativo.If code calls unmanaged code directly, it will not be allowed to run in many circumstances because code must be granted a high level of trust to call native code. Se a política for modificada para permitir que tal aplicativo seja executado, ele poderá reduzir significativamente a segurança do sistema, deixando o aplicativo livre para executar praticamente qualquer operação.If policy is modified to allow such an application to run, it can significantly weaken the security of the system, leaving the application free to perform almost any operation.

Além disso, o código que tem permissão para acessar o código não gerenciado pode, provavelmente, executar quase qualquer operação chamando uma API não gerenciada.Additionally, code that has permission to access unmanaged code can probably perform almost any operation by calling into an unmanaged API. Por exemplo, o código que tem permissão para chamar código não gerenciado não precisa FileIOPermission acessar um arquivo; ele pode simplesmente chamar uma API de arquivo não gerenciado (Win32) diretamente, ignorando a API de arquivo gerenciado que requer FileIOPermission.For example, code that has permission to call unmanaged code does not need FileIOPermission to access a file; it can just call an unmanaged (Win32) file API directly, bypassing the managed file API that requires FileIOPermission. Se o código gerenciado tiver permissão para chamar o código não gerenciado e chamar diretamente o código não gerenciado, o sistema de segurança não poderá impor restrições de segurança de forma confiável, já que o tempo de execução não pode impor essas restrições em código não gerenciado.If managed code has permission to call into unmanaged code and does call directly into unmanaged code, the security system will be unable to reliably enforce security restrictions, since the runtime cannot enforce such restrictions on unmanaged code.

Se você quiser que seu aplicativo execute uma operação que requer o acesso a código não gerenciado, ele deve fazer isso por meio de uma classe gerenciada confiável que encapsula a funcionalidade necessária (se tal classe existir).If you want your application to perform an operation that requires accessing unmanaged code, it should do so through a trusted managed class that wraps the required functionality (if such a class exists). Não crie uma classe wrapper por conta própria se já existir uma em uma biblioteca de classes segura.Do not create a wrapper class yourself if one already exists in a secure class library. A classe wrapper, que deve receber um alto grau de confiança para ter permissão para fazer a chamada em código não gerenciado, é responsável por exigir que seus chamadores tenham as permissões apropriadas.The wrapper class, which must be granted a high degree of trust to be allowed to make the call into unmanaged code, is responsible for demanding that its callers have the appropriate permissions. Se você usar a classe wrapper, seu código só precisará solicitar e receber as permissões exigidas pela classe wrapper.If you use the wrapper class, your code only needs to request and be granted the permissions that the wrapper class demands.

Confira tambémSee also