Riscos de segurança ou desempenho usando o SQL CLR [fechado]

11

Existe algum risco específico de segurança ou desempenho no uso do CLR no SQL Server?

SQLBen
fonte
Não, o código SQLCLR não pode fazer nada mais em um banco de dados do que um módulo de código T-SQL equivalente em execução no mesmo contexto de segurança. A proibição ignorada do CLR também evita a implantação do SSISDB, o que melhora drasticamente a segurança por meio de menos contas RDP, gerenciamento do sistema de arquivos e menos direitos, herança de backup nos planos de manutenção, criptografia completa de pacotes via TDE, para não falar das implantações e manutenção de pacotes SSIS pela seção de ambiente do SSISDB e falta de muitas funções C # no SSIS que requerem CLR.
Bryan Swan
1
Votei em reabrir esta questão porque acredito que tenha alguma relevância para a comunidade. A questão como está é uma questão válida, porque o nível de entrada para um DBA nas configurações de segurança do CLS é bastante alto. A resposta bem escrita de @SolomonRutzky fornece uma boa introdução às configurações de segurança do CLR que não são fornecidas neste nível simplista pela Microsoft.
John aka hot2use 5/17

Respostas:

10

A pergunta, como Remus apontou, é genérica demais para obter uma resposta, pois depende do contexto de qual funcionalidade deve ser usada e como será usada.

Em relação à "Segurança":

Se você está perguntando sobre algo que pode ser feito em uma montagem marcada com PERMISSION_SET = SAFE, não há nenhum problema que eu já tenha encontrado. E o SQLCLR é "mais seguro" do que usar xp_cmdshellou os maravilhosos sp_OA*procs (ou mesmo o sarcasmo) procs (ou mesmo os Procedimentos armazenados estendidos, mas espero que ninguém mais esteja criando nenhum deles).

Se você deseja conhecer o que "SAFE" significa em termos práticos, consulte este artigo: Escada para o SQLCLR Nível 3: Segurança (Assembléias Gerais e SAFE) (é necessário registro gratuito).

Se você estiver perguntando sobre algo que possa ser feito em uma montagem marcada com PERMISSION_SET = EXTERNAL_ACCESS, certamente haverá riscos novamente, dependendo de qual funcionalidade está sendo usada. Se você escrever uma rotina para ler diretórios e nomes de arquivos (isto é, somente leitura), será apenas uma questão do que deve ser visto e não visto. Se você estiver escrevendo um código que permita excluir um arquivo, o risco aumenta. Mas o que pode ser feito com esses recursos externos é controlado por:

  • se você está usando ou não representação:
    • sem representação significa que o acesso a recursos externos é feito por meio da conta "Fazer logon como" do serviço SQL Server. Qualquer que seja o acesso dessa conta, sua função SQLCLR poderá fazer.
    • usar representação significa que o logon no SQL Server que está executando a função, se esse logon corresponder a um logon do Windows, poderá fazer o que esse logon do Windows em particular estiver autorizado a fazer. Se o Logon no SQL Server for um Logon do SQL Server, a tentativa de usar a Representação receberá um erro.
  • Quais permissões são configuradas no recurso externo. Para acesso ao sistema de arquivos, isso é controlado através de ACLs em unidades NTFS.

Se você estiver perguntando sobre algo que possa ser feito em uma montagem marcada com PERMISSION_SET = UNSAFE, isso é bastante aberto. Muitas funcionalidades são consideradas apenas utilizáveis ​​em assemblies UNSAFE porque são questões de estabilidade e / ou comportamento consistente mais do que segurança ou desempenho. Por exemplo, em um assembly UNSAFE, é possível ter uma variável estática gravável. Normalmente, isso não é uma coisa boa a ser feita, pois as classes SQLCLR são compartilhadas em todas as sessões. Se sua intenção é compartilhar dados na memória em todas as sessões e tiver planejado condições de corrida (e realizado vários testes), você deve ficar bem, pois espera esse comportamento. Mas se você simplesmente desejasse que uma variável estática gravável armazenasse em cache um valor para uma determinada sessão, não fosse necessário procurá-la novamente ou calculá-la novamente e não estivesse ciente de que outras sessões estão lendo esse valor e possivelmente sobrescrevendo-o, bem, isso seria um problema.

Mas se você está preocupado com alguém escrevendo no Registro, mas ainda não possui nenhum código que grave no Registro, provavelmente não precisa se preocupar com isso ;-).

Se você deseja obter uma explicação detalhada de como EXTERNAL_ACCESS e UNSAFE funcionam em termos práticos, e a diferença entre definir TRUSTWORTHY ON(não preferido) e usar um Login assimétrico ou baseado em certificado ou chave, consulte este artigo: Stairway to SQLCLR Level 4: Segurança (Assembleias EXTERNAS e NÃO-SEGURAS) (é necessário registro gratuito).

Em relação ao "desempenho":

Tudo isso é uma questão do que você está tentando fazer e de como você o faz. Há algumas coisas que são muito mais rápidas no SQLCLR e outras mais lentas. Mas, assim como no T-SQL, é possível executar uma tarefa um tanto simples e / ou eficiente e torná-la complicada e / ou ineficiente, fazendo as coisas incorretamente. Mas o uso do SQL CLR não é inerentemente, por sua própria natureza, mais lento.

Solomon Rutzky
fonte
6

Montagens SQLCLR pode ser instalado com três níveis de acesso de segurança: SAFE | EXTERNAL_ACCESS | UNSAFE. Isso está amplamente documentado, consulte CREATE ASSEMBLYe Design de montagens :

Gerenciando a segurança do assembly
Você pode controlar quanto um assembly pode acessar os recursos protegidos pelo .NET Code Access Security ao executar o código gerenciado. Você faz isso especificando um dos três conjuntos de permissões ao criar ou modificar um assembly: SAFE, EXTERNAL_ACCESS ou UNSAFE.

SAFE
SAFE é o conjunto de permissões padrão e é o mais restritivo. O código executado por um assembly com permissões SAFE não pode acessar recursos externos do sistema, como arquivos, rede, variáveis ​​de ambiente ou registro. O código SAFE pode acessar dados dos bancos de dados locais do SQL Server ou executar cálculos e lógica de negócios que não envolvem o acesso a recursos fora dos bancos de dados locais.
A maioria dos assemblies realiza tarefas de computação e gerenciamento de dados sem precisar acessar recursos fora do SQL Server. Portanto, recomendamos o SAFE como o conjunto de permissões de montagem.

EXTERNAL_ACCESS
EXTERNAL_ACCESS permite que os assemblies acessem certos recursos externos do sistema, como arquivos, redes, serviços da Web, variáveis ​​ambientais e o registro. Somente logons do SQL Server com permissões EXTERNAL ACCESS podem criar assemblies EXTERNAL_ACCESS. Os assemblies SAFE e EXTERNAL_ACCESS podem conter apenas código com segurança de tipo verificável. Isso significa que esses assemblies podem acessar apenas classes por meio de pontos de entrada bem definidos, válidos para a definição de tipo. Portanto, eles não podem acessar arbitrariamente buffers de memória que não pertencem ao código. Além disso, eles não podem executar operações que possam ter um efeito adverso na robustez do processo do SQL Server.

UNSAFE
O UNSAFE fornece aos assemblies acesso irrestrito aos recursos, dentro e fora do SQL Server. O código que está sendo executado de dentro de um assembly UNSAFE pode chamar código não gerenciado. Além disso, a especificação de UNSAFE permite que o código no assembly execute operações que são consideradas inseguras pelo verificador CLR. Essas operações podem acessar os buffers de memória no espaço de processo do SQL Server de maneira descontrolada. Os assemblies UNSAFE também podem potencialmente subverter o sistema de segurança do SQL Server ou do Common Language Runtime. Permissões UNSAFE devem ser concedidas apenas a assembléias altamente confiáveis ​​por desenvolvedores ou administradores experientes. Somente membros da função de servidor fixa sysadmin podem criar assemblies UNSAFE.

Existem restrições adicionais nos atributos de CLR permitidos e apenas um subconjunto dos .Net Framework Assemblies é suportado. Mais uma vez, consulte a documentação vinculada.

Quanto ao desempenho, o pensamento mais importante é lembrar que o SQL Server é um ambiente multitarefa cooperativo, enquanto o CLR não. O código SQLCLR deve chamar Thread.BeginThreadAffinity()sempre que monopolizar a CPU por qualquer duração (incluindo bloqueio). Adam Machanic tem uma excelente apresentação sobre o assunto, assista a Dados mais rapidamente: técnicas de desempenho do Microsoft SQL Server com SQLCLR .

O tópico é vasto e a pergunta vaga. O SQLCLR pode executar algumas tarefas exclusivas que nenhum outro recurso pode corresponder. E o SQLCLR é apenas mais uma arma no arsenal do SQL Server com a qual você pode dar um tiro no pé com desempenho ou segurança. Leia a documentação.

Remus Rusanu
fonte
Obrigado por este Remus. Sei que a pergunta é vaga, mas há algum problema de segurança com relação a isso? graças
SQLBen