SQL Serverのdynamic-sqlで識別子を引用する関数は何ですか?


11

動的SQL生成のために識別子を安全に引用するSQL Serverの方法は何ですか。

動的に生成されたステートメントに動的に生成された列名を指定すると、列自体がSQLインジェクション攻撃ではないことをどのように確認できますか?

SQL文があるとします。

SELECT [$col] FROM table;

これは本質的に同じです

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

インジェクション攻撃を阻止するもの

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

その結果

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

回答:


14

あなたが探している機能はQUOTENAME

角かっこテクノロジを実際に使用することで、文字列を安全にカプセル化して、ホットSQLインジェクション攻撃の防止に役立てることができます。

角括弧を何かの周りに付けただけで安全に引用符で囲まれないことに注意してください。ただし、オブジェクト名に無効な文字があるとコードエラーが発生するのを回避できます。

良いコード

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

悪いコード

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

具体的な例を挙げると...

以下は、初期入力に対して正常に動作します

DECLARE @ObjectName SYSNAME = 'sysobjects';

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

EXEC (@dynSql);

しかし、悪意のある入力により、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);

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);

無効なオブジェクト名 'sysobjects]; SELECT'これは実行された任意のコードです。テーブルが削除されたか、権限が付与された可能性があります '-'。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.