Este artigo foi traduzido por máquina. Para visualizar o arquivo em inglês, marque a caixa de seleção Inglês. Você também pode exibir o texto Em inglês em uma janela pop-up, movendo o ponteiro do mouse sobre o texto.
Tradução
Inglês

Noções básicas da segurança de acesso do código

 

System_CAPS_cautionCuidado

Segurança de Acesso do Código e Código Parcialmente Confiável

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).  O CAS no .NET Framework não deve ser usado como um mecanismo de imposição de limites de segurança com base na origem do código ou em outros aspectos da identidade. Estamos atualizando nossas diretrizes para refletir que o CAS e o Código Transparente de Segurança não terão suporte como um limite de segurança com código parcialmente confiável, especialmente o código de origem desconhecida. Não aconselhamos carregar e executar códigos de origens desconhecidas sem a adoção de medidas de segurança alternativas no local.

Essa política é aplicável à todas as versões do .NET Framework, mas não é aplicável ao .NET Framework incluído no Silverlight.

Todos os aplicativos que tem como alvo o common language runtime (ou seja, todos os aplicativos gerenciados) devem interagir com o sistema de segurança do tempo de execução. Quando um aplicativo gerenciado é carregado, o seu host lhe concede automaticamente um conjunto de permissões. Essas permissões são determinadas pelas configurações de segurança local do host ou o aplicativo está em área restrita. Dependendo dessas permissões, o aplicativo é executado corretamente ou gera uma exceção de segurança.

O host padrão para aplicativos de desktop permite que o código executado em confiança total. Portanto, se seu aplicativo for destinado para a área de trabalho, ele tem uma permissão irrestrita definido. Outros hosts ou áreas restritas fornecem um conjunto de aplicativos de permissões limitado. Como o conjunto de permissões pode ser alterado de host para host, você deve projetar seu aplicativo para usar somente as permissões que permite que o host de destino.

Você deve estar familiarizado com os seguintes conceitos de segurança de acesso do código para escrever aplicativos efetivos destinados a common language runtime:

  • Código fortemente tipado: código fortemente tipado é o código que acessa tipos somente em modos permitidos e bem definidos. Por exemplo, dada uma referência de objeto válido, código fortemente tipado pode acessar memória em offsets fixos que correspondem aos membros de campo reais. Se o código acessa a memória em offsets arbitrários fora do intervalo de memória que pertence a esse objeto publicamente exposto campos, não é fortemente tipado. Para habilitar o código para se beneficiar da segurança de acesso ao código, você deve usar um compilador que gera código fortemente tipado verificável. Para obter mais informações, consulte o código de tipos seguros verificável escrita seção mais adiante neste tópico.

  • Sintaxe imperativa e declarativa: código que tem como alvo o common language runtime pode interagir com o sistema de segurança de solicitar permissões, exigindo que os chamadores têm permissões especificadas e substituindo determinadas configurações de segurança (dada privilégios suficientes). Usar duas formas de sintaxe para interagir programaticamente com o sistema de segurança do .NET Framework: sintaxe declarativa e sintaxe imperativa. Chamadas declarativas são executadas usando atributos; chamadas imperativas são executadas usando novas instâncias de classes em seu código. Algumas chamadas podem ser executadas apenas imperativa, outras podem ser executadas apenas declarativamente e algumas chamadas podem ser executadas de qualquer maneira.

  • Proteger bibliotecas de classes: uma biblioteca de classe seguras usa demandas de segurança para garantir que os chamadores da biblioteca tem permissão para acessar os recursos que expõe a biblioteca. Por exemplo, uma biblioteca de classe seguras pode ter um método para criar arquivos que seriam exigem que os chamadores tem permissões para criar arquivos. O .NET Framework consiste em bibliotecas de classe seguras. Você deve estar ciente das permissões necessárias para acessar qualquer biblioteca que usa seu código. Para obter mais informações, consulte o usando bibliotecas de classe Secure seção mais adiante neste tópico.

  • Código transparent: iniciando com o .NET Framework 4, além de identificar as permissões específicas, você também deve determinar se seu código deve ser executado como transparente de segurança. Código transparente de segurança não pode chamar tipos ou membros que são identificados como críticas de segurança. Essa regra se aplica a aplicativos de confiança total, bem como aplicativos parcialmente confiáveis. Para obter mais informações, consulte Código transparente de segurança.

A compilação Just-in-time (JIT) executa um processo de verificação que examina o código e tenta determinar se o código é fortemente tipado. Código que é comprovadamente durante a verificação para ser fortemente tipado é chamado código fortemente tipado verificável. Código pode ser fortemente tipado, ainda pode não ser fortemente tipado verificável devido às limitações do processo de verificação ou do compilador. Nem todos os idiomas são fortemente tipadas e alguns compiladores de linguagem, como Microsoft Visual C++, não é possível gerar código gerenciado fortemente tipado verificável. Para determinar se o compilador de linguagem que você usar gera código verificável fortemente tipado, consulte a documentação do compilador. Se você usar um compilador de linguagem que gera código fortemente tipado verificável somente quando você evitar determinadas construções de linguagem, talvez você queira usar o ferramenta PEVerify para determinar se o seu código é fortemente tipado verificável.

Código que não seja fortemente tipado verificável pode tentar executar se a política de segurança permite que o código ignorar essa verificação. No entanto, como segurança de tipo é uma parte essencial do mecanismo do tempo de execução para isolar assemblies, segurança não pode ser aplicada confiavelmente se código viola as regras de segurança de tipos. Por padrão, o código que não seja fortemente tipado é permitido seja executada apenas se originou no computador local. Portanto, o código móvel deve ser fortemente tipado.

Se seu código solicita e recebe as permissões necessárias para a biblioteca de classes, ele poderá acessar a biblioteca e os recursos que expõe a biblioteca estará protegidos contra acesso não autorizado. Se seu código não tem as permissões apropriadas, ele não poderá acessar a biblioteca de classe e código mal-intencionado não poderá usar o código indiretamente acessar recursos protegidos. Outro código que chama o código também deve ter permissão para acessar a biblioteca. Se isso não acontecer, seu código será restrito executem também.

Segurança de acesso ao código não elimina a possibilidade de erro humano na escrita de códigos. No entanto, se seu aplicativo usa bibliotecas de classe seguras para acessar recursos protegidos, o risco de segurança para o código do aplicativo é reduzido, porque as bibliotecas de classes intimamente são examinadas para problemas potenciais de segurança.

Sintaxe de segurança declarativa usa atributos para colocar informações de segurança para o metadados do seu código. Atributos podem ser colocados no nível de assembly, classe ou membro, para indicar o tipo de solicitação, por demanda ou substituição que você deseja usar. As solicitações são usadas em aplicativos destinados a 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 quer. Demandas e substituições são usadas em bibliotecas para ajudar a proteger recursos de chamadores ou para substituir o comportamento padrão de segurança.

System_CAPS_noteObservação

No .NET Framework 4, houve alterações importantes para o modelo de segurança do .NET Framework e terminologia. Para obter mais informações sobre essas opções, consulte Alterações na segurança do .NET Framework.

Para usar a segurança declarativa chamadas, você deve inicializar os dados de estado do objeto de permissão para que ele represente o formulário particular de permissão que é necessário. Cada permissão interna tem um atributo que é passado um SecurityAction enumeração para descrever o tipo de operação de segurança você deseja executar. No entanto, as permissões também aceitam seus próprios parâmetros que são exclusivos a eles.

O fragmento de código a seguir mostra a sintaxe declarativa para solicitar que os chamadores do seu código tenham uma permissão personalizada chamada MyPermission. Essa permissão é uma permissão personalizada hipotética e não existe no .NET Framework. Neste exemplo, a chamada declarativa é colocada diretamente antes da definição de classe, especificando que essa permissão seja aplicado ao nível de classe. O atributo é passado um SecurityAction. Demand para especificar que os chamadores devem ter essa permissão para executar.

[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.
   }
}

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. Você pode usar sintaxe obrigatória para realizar demandas e substituições, mas não nas solicitações.

Antes de você chama a segurança, você deve inicializar os dados de estado do objeto de permissão para que ele represente o formulário particular da permissão que é necessário. Por exemplo, ao criar um FileIOPermission do objeto, você pode usar o construtor para inicializar o FileIOPermission para que ele represente o acesso irrestrito a todos os arquivos ou nenhum acesso a arquivos de objeto. Ou, você pode usar outro FileIOPermission objeto, passando o objeto de parâmetros que indicam o tipo de acesso que deseja para representar (ou seja, leitura, acrescentar ou gravação) e arquivos que você deseja que o objeto para proteger.

Além de usar a sintaxe de segurança imperativa para invocar um objeto de segurança único, você pode usá-lo para inicializar um grupo de permissões em um conjunto de permissões. Por exemplo, essa técnica é a única maneira de realizar confiável assert chama em várias permissões em um método. Use o PermissionSet e NamedPermissionSet classes para criar um grupo de permissões e, em seguida, chamar o método apropriado para invocar a chamada de segurança desejado.

Você pode usar sintaxe obrigatória para realizar demandas e substituições, mas não nas solicitações. Você pode usar a sintaxe imperativa para atender às demandas e substituições em vez de sintaxe declarativa quando informações necessárias para inicializar o estado de permissão torna-se conhecido somente em tempo de execução. Por exemplo, se você quiser garantir que os chamadores tem permissão para ler um determinado arquivo, mas você não souber o nome do arquivo até o tempo de execução, use uma demanda imperativa. Você também pode optar por usar verificações imperativas em vez de verificações declarativas quando você precisa determinar o tempo de execução se mantém uma condição e, com base no resultado do teste, fazer uma demanda de segurança (ou não).

O fragmento de código a seguir mostra a sintaxe imperativa para solicitar que os chamadores do seu código tenham uma permissão personalizada chamada MyPermission. Essa permissão é uma permissão personalizada hipotética e não existe no .NET Framework. Uma nova instância de MyPermision é criado no MyMethod, preservando apenas esse método com a chamada de segurança.

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.
   }
}

A maioria dos aplicativos e componentes (exceto bibliotecas seguras) não devem diretamente chamar código não gerenciado. Há vários motivos para isso. Se o código chama diretamente o código não gerenciado, ele não poderá ser executado em muitas circunstâncias, pois o código deve receber um alto nível de confiança para chamar código nativo. Se a política é modificada para permitir que esse aplicativo ser executado, ele pode reduzir significativamente a segurança do sistema, deixando o aplicativo pode executar quase qualquer operação.

Além disso, o código que tenha permissão para acessar código não gerenciado provavelmente pode executar quase qualquer operação chamando uma API não gerenciada. Por exemplo, o código que tenha permissão para chamar código não gerenciado não precisa FileIOPermission para acessar um arquivo; apenas pode chamar um arquivo (Win32) não gerenciado API diretamente, ignorando o arquivo gerenciado API que requer FileIOPermission. Se o código gerenciado tenha permissão para chamar código não gerenciado e chamar diretamente em código não gerenciado, o sistema de segurança poderão confiável impor restrições de segurança, pois o tempo de execução não é possível impor restrições em código não gerenciado.

Se desejar que seu aplicativo para executar uma operação que requer 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 houver tal classe). Não crie uma classe wrapper mesmo se já existir em uma biblioteca de classe seguras. A classe de wrapper, que deve ser concedida a um alto grau de confiança para poder fazer a chamada para código não gerenciado, é responsável por exigindo que os chamadores tem as permissões apropriadas. Se você usar a classe de wrapper, seu código só precisa solicitar e receber as permissões que exige a classe de wrapper.

Mostrar: