什么函数在带有 SQL Server 的动态 sql 中引用标识符?

Eva*_*oll 11 security sql-server sql-injection

什么是用于动态 sql 生成的安全引用标识符的 SQL Server 方法。

我如何确保为动态生成的语句提供动态生成的列名,该列本身不是 SQL 注入攻击。

假设我有一个 SQL 语句,

SELECT [$col] FROM table;
Run Code Online (Sandbox Code Playgroud)

本质上与

'SELECT [' + $col + '] FROM table;'
Run Code Online (Sandbox Code Playgroud)

什么可以阻止注入攻击

$col = "name] FROM sys.objects; \r\n DROP TABLE my.accounts; \r\n\ --";
Run Code Online (Sandbox Code Playgroud)

导致

SELECT [$col] FROM table;
Run Code Online (Sandbox Code Playgroud)

Eri*_*ing 14

您正在寻找的功能是QUOTENAME

通过方括号技术的实际使用,可以安全地封装字符串,帮助防范热SQL注入攻击。

请注意,仅在某些内容周围加上方括号并不能安全地将其引用出来,尽管您可以避免代码因对象名称中的无效字符而出错。

好代码

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

错误代码

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

举个具体的例子...

以下适用于初始输入

DECLARE @ObjectName SYSNAME = 'sysobjects';

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

EXEC (@dynSql);
Run Code Online (Sandbox Code Playgroud)

但是对于恶意输入,它很容易受到 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);
Run Code Online (Sandbox Code Playgroud)

使用QUOTENAME正确转义嵌入]并防止发生尝试的 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);
Run Code Online (Sandbox Code Playgroud)

Invalid object name 'sysobjects];SELECT '这是执行的一些任意代码。它可能已删除表或授予权限'--'。