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
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:
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!
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.
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
: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: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!