Segurança em SQLCLR


O .NET Framework 2.0 em conjunto com o SQL Server 2005 permite criarmos Stored Procedures, FunctionsTriggers em código gerenciado (C# ou VB.NET). Quando o código que colocamos dentro destes objetos são códigos puramente de acesso à dados, não encontramos problemas no momento de catalogar o Assembly dentro do SQL Server.

Alguns cuidados devem ser tomados quando, dentro destes códigos, há acesso à recursos externos, como IO, Threading, SMTP, etc. Ao catalogar o Assembly, podemos definir uma propriedade chamada PERMISSION_SET, que aceita uma das tres opções a seguir:

  • SAFE: É o padrão. Neste modo o Assembly somente poderá rodar no contexto local, mas não através do SqlClient. Previne também o acesso através de recursos externos e de código não gerenciado.
  • EXTERNAL_ACCESS: É o mesmo que SAFE, somente habilitando o acesso aos recursos externos.
  • UNSAFE: Acesso irrestrito, desde que o Assembly seja assinado e catalogado por um usuário que seja membro do grupo sql_admins.

Quando temos acesso a recurso externo, então teoricamente devemos definir a PERMISSION_SET como EXTERNAL_ACCESS. O problema é que, por padrão, isso não é permitido e se tentarmos, a seguinte mensagem de erro será retornada:

CREATE ASSEMBLY for assembly ‘%’ failed because assembly ‘%’ is not authorized for PERMISSION_SET = EXTERNAL_ACCESS.  The assembly is authorizedwhen either of the following is true: the database owner (DBO) has EXTERNAL ACCESS ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with EXTERNAL ACCESS ASSEMBLY permission.

Como a própria mensagem de erro diz, bastaríamos definir a propriedade TRUSTWORTHY do banco de dados como ON, permitindo assim o acesso aos recursos utilizados. O problema é que isso não é recomendado pela Microsoft, já que possibilitaria que qualquer Assembly seja catalogado, até mesmo Assemblies maliciosos.

Para contornar o problema e catalogar o Assembly concedendo a ele, privilégios para acesso à recursos externos, a solução é a criação de de uma chave assimétrica (baseada em chave pública/privada). Para isso, utilizamos a opção CREATE ASYMMETRIC KEY juntamente com a opção FROM EXECUTABLE FILE; isso fará com que a chave pública seja importada do Assembly (devidamente assinado com Strong Name) onde está o código gerenciado com os objetos SQL e irá criá-la dentro do banco de dados master. Depois disso, devemos criar um login e vinculá-lo a esta chave assimétrica que acabamos de gerar. Finalmente damos permissão para acesso à recursos externos à este login, como é mostrado no código abaixo:

CREATE ASYMMETRIC KEY MinhaChave FROM EXECUTABLE FILE = ‘C:SQLExtensibility.dll’
CREATE LOGIN MeuLogin FROM ASYMMETRIC KEY MinhaChave
GRANT EXTERNAL ACCESS ASSEMBLY TO MeuLogin

Depois disso, basta catalogar o Assembly via IDE ou até mesmo via código, concedendo à ele EXTERNAL_ACCESS, como é mostrado no código abaixo:

CREATE ASSEMBLY RecursosExtras
FROM ‘C:SQLExtensibility.dll’
WITH PERMISSION_SET = EXTERNAL_ACCESS

Apesar da primeira forma (TRUSTWORTHY) ser muito mais simples, o melhor é seguir a recomendação da Microsoft, não concedendo TRUSTWORTHY para a base de dados que apenas utilizam recursos externos a partir de um Assembly CLR.

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