Apa fungsi mengutip pengidentifikasi dalam dynamic-sql dengan SQL Server?

11

Apa metode SQL Server pengidentifikasi kutipan aman untuk generasi sql dinamis.

Bagaimana saya memastikan diberikan nama kolom yang dihasilkan secara dinamis untuk pernyataan yang dihasilkan secara dinamis bahwa kolom itu sendiri bukan serangan injeksi SQL.

Katakanlah saya punya Pernyataan SQL,

SELECT [$col] FROM table;

yang pada dasarnya sama dengan

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

Apa yang menghentikan serangan injeksi di mana

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

Yang menghasilkan

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

Jawaban:

14

Fungsi yang Anda cari adalah QUOTENAME!

Melalui penggunaan praktis teknologi braket persegi, Anda dapat dengan aman merangkum string untuk membantu dalam pencegahan serangan injeksi SQL panas.

Perhatikan bahwa hanya menempelkan tanda kurung di sekitar sesuatu tidak dengan aman mengutipnya, meskipun Anda dapat menghindari kesalahan kode dengan karakter yang tidak valid dalam nama objek.

Kode yang baik

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

Kode salah

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

Untuk memberikan contoh spesifik ...

Berikut ini berfungsi dengan baik untuk input awal

DECLARE @ObjectName SYSNAME = 'sysobjects';

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

EXEC (@dynSql);

Tetapi dengan input berbahaya itu rentan terhadap injeksi 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);

Menggunakan QUOTENAMEdengan benar lolos dari tertanam ]dan mencegah upaya injeksi SQL terjadi.

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

Nama objek 'sysobjects]; SELECT' Ini adalah beberapa kode arbitrer yang dijalankan. Mungkin telah menjatuhkan tabel atau memberikan izin '-'.

Erik Darling
sumber