Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como limpar (evitar injeção de SQL) SQL dinâmico no SQL Server?


Acredito que existem três casos diferentes com os quais você deve se preocupar:
  • strings (qualquer coisa que exija aspas):'''' + replace(@string, '''', '''''') + ''''
  • nomes (qualquer coisa em que aspas não sejam permitidas):quotename(@string)
  • coisas que não podem ser citadas:isso requer lista de permissões

Observação :Tudo em uma variável string (char , varchar , nchar , nvarchar , etc.) provenientes de fontes controladas pelo usuário devem usar um dos métodos acima. Isso significa que mesmo as coisas que você espera que sejam números são citadas se forem armazenadas em variáveis ​​de string.

Para obter mais detalhes, consulte a Microsoft Magazine (Link obsoleto:2016-10-19) .

Aqui está um exemplo usando todos os três métodos:
EXEC 'SELECT * FROM Employee WHERE Salary > ''' +
     REPLACE(@salary, '''', '''''') +   -- replacing quotes even for numeric data
     ''' ORDER BY ' + QUOTENAME(@sort_col) + ' ' +  -- quoting a name
     CASE @sort_dir WHEN 'DESC' THEN 'DESC' END     -- whitelisting

Observe também que, fazendo todas as operações de string inline no EXEC declaração não há preocupação com problemas de truncamento. Se você atribuir os resultados intermediários a variáveis, você deve certifique-se de que as variáveis ​​sejam grandes o suficiente para conter os resultados. Se você fizer SET @result = QUOTENAME(@name) você deve definir @result para conter pelo menos 258 (2 * 128 + 2) caracteres. Se você fizer SET @result = REPLACE(@str, '''', '''''') você deve definir @result ter o dobro do tamanho de @str (assuma todos os caracteres em @str pode ser uma citação). E, claro, a variável string que contém a instrução SQL final deve ser grande o suficiente para conter todo o SQL estático mais todas as variáveis ​​de resultado.