SandBoxing em ASP.NET


Como já havia mencionado aqui na seção de segurança, uma boa prática é não permitir que aplicações Web sejam executadas em FullTrust (padrão). Esse nível concede a aplicação Web, acesso a todos os recursos do servidor, tais como, acesso a sistema de arquivos, banco de dados, acesso ao Registry, execução de código não gerenciado, etc.. São permissões que, muitas vezes, não são necessárias e, se concedidas à alguém com más intenções, poderá comprometer a segurança do servidor e da rede.

Para evitar isso, voce pode configurar este nível de segurança tanto no arquivo Web.Config da aplicação ou, se desejar, no arquivo Web.Config que está a nível de servidor. Se optar por alterar o segundo, todas as aplicações ASP.NET que correm naquele servidor, utilizarão esse nível. E ainda, neste segundo (servidor), é importante que voce também altere o atributo allowOverride para false, justamente para que isso não possa ser sobrescrito pelas aplicações. Abaixo um exemplo de como alterar o nível de segurança apenas em uma aplicação:

<configuration>
    <system.web>
      <trust level=”Medium” />
    </system.web>
</configuration>

Com isso, voce terá restrições ao rodar o seu código. Um exemplo é com relação ao sistema de arquivos. Com o nível Medium, voce apenas poderá ler e escrever arquivos no diretório da aplicação e nada mais. Se desejar ler ou salvar um arquivo em C:Temp uma exceção será atirada.

Uma vez negado o acesso a todo o sistema de arquivos, pode ser necessário que a aplicação necessite acessar o diretório C:Temp. Com essa necessidade, temos duas técnicas que podemos recorrer para conceder o acesso que acabamos de negar. Essas técnicas estão descritas abaixo:

  1. Modificar o arquivo de segurança: essa técnica consiste na alteração do arquivo de configuração que está relacionado com o nível de segurança especificado. Como definimos Medium, as permissões que são concedidas, estão contidas dentro do arquivo web_mediumtrust.config, no diretório de configuração do .NET Framework 2.0.
  2. Utilizar a técnica de SandBoxing: SandBoxing (tema do post) consiste em voce fatorar, ou melhor, isolar o seu código em um outro Assembly, concedendo a este, permissões específicas para o que ele deseja fazer (no nosso caso é ler/salvar arquivos no diretório C:Temp).

O isolamento consiste basicamente em gerar uma DLL (projeto Class Library) e assiná-la com um strong-name. Uma vez criada essa DLL voce deve adicioná-la no GAC que, por padrão, Assemblies lá colocados ganham FullTrust. Se o GAC não estiver acessível, então voce deverá colocar o Assembly no diretório Bin da aplicação e ainda mudar o arquivo de configuração do nível de segurança, concendendo mais privilégios para o Assembly, baseando-se no publicador ou strong-name. É importante dizer que para ambos os casos é necessário que voce tenha privilégios administrativos no servidor.

Ainda há mais um detalhe na criação da DLL. É extremamente necessário que voce defina o atributo AllowPartiallyTrustedCallers (System.Security) no arquivo AssemblyInfo. Esse atributo permitirá que o componente seja chamado através de aplicações (código) parcialmente confiáveis (partial trust).

Finalmente voce executa a aplicação Web, fazendo chamada para este componente e, quando tenta criar um arquivo texto no C:Temp, uma exceção do tipo SecurityException é atirada dizendo que voce – ainda – não tem permissões para isso (FileIOPermission). Isso ocorre justamente porque, momentos antes que o componente vai salvar o arquivo no disco, ele verifica as permissões de toda a stack; esse processo é chamado do stack walk e é onde ele percorre todas as chamadas para ver se todo mundo possui a permissão necessária para efetuar a tarefa.

No nosso caso, como adicionamos o componente no GAC, o componente possui a permissão, pois é atribuído a ele FullTrust; mas como o stack walk também verificará a aplicação Web que chama o componente, essa por sua vez, não terá a permissão necessária e, consequentemente, a exceção será atirada. Para permitir que tudo corra bem, então é necessário que voce modifique a stack, aplicando um Assert (cuidado com esse método) a permissão que está sendo requisitada. Esse método apenas verificará se o componente tem permissão, não percorrendo todos os chamadores. Sendo assim, o código do componente tem uma ligeira mudança:

public void WriteFile(string file, string content)
{
    new FileIOPermission(FileIOPermissionAccess.AllAccess, file).Assert();
    using (StreamWriter sw = new StreamWriter(file))
        sw.Write(content);
}

Obviamente que isso é apenas um exemplo de teste. No mundo real, isso é bastante útil, já que muitas pessoas não se preocupam, e sempre deixam a configuração padrão do .NET que, em muitos casos, não é necessária e, neste caso, pode comprometer a segurança do servidor, principalmente, se ele for público.

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s