Qual função cita um identificador no sql dinâmico com o SQL Server?

11

Qual é o método do SQL Server de identificadores de cotação segura para geração dinâmica de sql.

Como garantir um nome de coluna gerado dinamicamente para uma instrução gerada dinamicamente que a própria coluna não é um ataque de injeção de SQL.

Digamos que eu tenho uma instrução SQL,

SELECT [$col] FROM table;

que é essencialmente o mesmo que

'SELECT [' + $col + '] FROM table;'

O que interrompe um ataque de injeção onde

$col = "name] FROM sys.objects; \r\n DROP TABLE my.accounts; \r\n\ --";

Resultando em

SELECT [name] FROM sys.objects;
DROP TABLE my.accounts;
-- ] FROM table;
Evan Carroll
fonte

Respostas:

14

A função que você está procurando é QUOTENAME!

Através do uso prático da tecnologia de colchete, você pode encapsular com segurança seqüências de caracteres para ajudar na prevenção de ataques de injeção de SQL quentes.

Observe que apenas colocar colchetes em torno de algo não é citado com segurança, embora você possa evitar erros de código com caracteres inválidos nos nomes de objetos.

Good code

DECLARE @sql NVARCHAR(MAX) = N''
SELECT @sql = 'SELECT ' + QUOTENAME(d.name) + ' FROM your_mom'
FROM sys.databases AS d

Código incorreto

DECLARE @sql NVARCHAR(MAX) = N''
SELECT @sql = 'SELECT [' + d.name + '] FROM your_mom'
FROM sys.databases AS d

Para dar um exemplo específico ...

O seguinte funciona bem para a entrada inicial

DECLARE @ObjectName SYSNAME = 'sysobjects';

DECLARE @dynSql NVARCHAR(MAX) = 'SELECT COUNT(*) FROM [' + @ObjectName + ']';

EXEC (@dynSql);

Mas com entrada maliciosa, é vulnerável à injeção de SQL

DECLARE @ObjectName SYSNAME = 'sysobjects];SELECT ''This is some arbitrary code executed. It might have dropped a table or granted permissions''--'

DECLARE @dynSql NVARCHAR(MAX) = 'SELECT  COUNT(*)  FROM [' + @ObjectName + ']';

EXEC (@dynSql);

O uso QUOTENAMEescapa corretamente do incorporado ]e impede a tentativa de injeção de SQL.

DECLARE @ObjectName SYSNAME = 'sysobjects];SELECT ''This is some arbitrary code executed. It might have dropped a table or granted permissions''--'

DECLARE @dynSql NVARCHAR(MAX) = 'SELECT  COUNT(*)  FROM ' + QUOTENAME(@ObjectName);

EXEC (@dynSql);

Nome de objeto inválido 'sysobjects]; SELECT' Este é um código arbitrário executado. Pode ter descartado uma tabela ou concedido permissões '-'.

Erik Darling
fonte