Rumah > Soal Jawab > teks badan
rreeee
P粉4349968452023-11-08 20:39:55
Setahu saya, anda tidak boleh menggunakan pertanyaan berparameter untuk melaksanakan pernyataan DDL/menentukan nama jadual, sekurang-kurangnya tidak dalam Oracle atau Sql Server. Jika saya terpaksa mempunyai fungsi TruncateTable yang gila, dan terpaksa mengelakkan suntikan SQL, maka apa yang saya akan lakukan ialah mencipta prosedur tersimpan yang menyemak sama ada input ialah jadual yang boleh dipotong dengan selamat.
-- Sql Server specific! CREATE TABLE TruncableTables (TableName varchar(50)) Insert into TruncableTables values ('MyTable') go CREATE PROCEDURE MyTrunc @tableName varchar(50) AS BEGIN declare @IsValidTable int declare @SqlString nvarchar(50) select @IsValidTable = Count(*) from TruncableTables where TableName = @tableName if @IsValidTable > 0 begin select @SqlString = 'truncate table ' + @tableName EXECUTE sp_executesql @SqlString end END
P粉7383463802023-11-08 09:41:58
Nasihat yang paling biasa untuk memerangi suntikan SQL ialah menggunakan parameter pertanyaan SQL (beberapa orang di urutan ini telah mencadangkan untuk melakukan ini).
Ini adalah jawapan yang salah dalam kes ini. Anda tidak boleh menggunakan parameter pertanyaan SQL pada nama jadual dalam pernyataan DDL.
Parameter pertanyaan SQL hanya boleh digunakan sebagai ganti nilai literal dalam ungkapan SQL. Ini adalah standard untuk setiap pelaksanaan SQL.
Apabila anda mempunyai nama jadual, cadangan saya untuk menghalang suntikan SQL adalah untuk mengesahkan rentetan input terhadap senarai nama jadual yang diketahui.
Anda boleh mendapatkan senarai nama jadual yang sah dari INFORMATION_SCHEMA
:
SELECT table_name FROM INFORMATION_SCHEMA.Tables WHERE table_type = 'BASE TABLE' AND table_name = @tableName
Kini anda boleh menghantar pembolehubah input sebagai parameter SQL kepada pertanyaan ini. Jika pertanyaan tidak mengembalikan baris, anda tahu input tidak sah dan tidak boleh digunakan sebagai jadual. Jika pertanyaan mengembalikan baris, ia sepadan, jadi anda boleh menggunakannya dengan lebih yakin.
Anda juga boleh mengesahkan nama jadual terhadap senarai jadual tertentu yang anda takrifkan sebagai tersedia untuk dipangkas oleh aplikasi, seperti yang @John Buchanan cadangkan.
Walaupun selepas mengesahkan bahawa tableName
wujud sebagai nama jadual dalam RDBMS anda, saya juga akan mencadangkan untuk mengehadkan nama jadual, sekiranya anda menggunakan nama jadual dengan ruang atau aksara khas Dalam Microsoft SQL Server, pembatas pengecam lalai ialah kurungan segi empat sama:
string sqlStatement = string.Format("TRUNCATE TABLE [{0}]", tableName);
Kini anda hanya berisiko untuk suntikan SQL jika tableName
sepadan dengan jadual sebenar, dan anda sebenarnya menggunakan kurungan segi empat sama dalam nama jadual anda!