[英]Safely query SQL table with variable table name
我正在嘗試編寫一些通用的代碼來從表中檢索身份,這涉及制作一個不安全的查詢字符串以注入表名。
我到處都讀到無法安全地注入表名。 因此,我想查詢表是否存在,然后根據結果執行實數查詢或偽查詢。
var unsafeTableQuery = "SELECT [Id] FROM [dbo].[" + tableName + "] WHERE [BulkInsertSessionID] = @bulkInsertSessionId";
var guardQuery =
"DECLARE @Exists BIT = ( SELECT CAST( COUNT(1) AS BIT ) FROM sys.tables WHERE name = @TableName AND type = 'U' );" +
"IF (@Exists = 0) SELECT TOP 0 NULL 'Id'" +
"ELSE " + unsafeTableQuery;
var cmd = new SqlCommand(guardQuery, conn, tran);
cmd.Parameters.Add(new SqlParameter("@TableName", tableName));
cmd.Parameters.Add(new SqlParameter("@bulkInsertSessionId", bulkInsertSessionId));
using (SqlDataReader reader = cmd.ExecuteReader())
{
int index = 0;
while (reader.Read())
{
int id = (int)reader[0];
entities[index++].Id = id;
}
}
即使我的連接不安全,我還是先通過sys.tables
參數查詢表名稱。 而且,如果它不存在,則IF..ELSE
塊將永遠不會進入不安全的查詢。
為了更容易閱讀,我希望運行以下查詢:
DECLARE @Exists BIT = ( SELECT CAST( COUNT(1) AS BIT ) FROM sys.tables WHERE name = @TableName AND type = 'U' );
IF(@Exists = 0)
SELECT TOP 0 NULL 'Id'
ELSE
SELECT [Id] from <InjectedTableName> where BulkInsertSessionID = @bulkSessionId
我以為這是安全的假設是否正確?
假設您的用戶有權更改變量tableName
。 我想一些用戶以某種形式鍵入它。 假設他鍵入以下內容:
Users]; DROP TABLE Users;--
然后,您的整個命令將是:
DECLARE @Exists BIT = ( SELECT CAST( COUNT(1) AS BIT ) FROM sys.tables WHERE name = @TableName AND type = 'U' );
IF(@Exists = 0)
SELECT TOP 0 NULL 'Id'
ELSE
SELECT [Id] from [Users]; DROP TABLE Users;-- where BulkInsertSessionID = @bulkSessionId
這將完成其IF ELSE
部分,然后轉到下一條語句:
DROP TABLE Users;
注意,因為沒有BEGIN END
,即使沒有執行ELSE
部分,drop語句也將始終執行。 請注意,其余部分已被注釋掉。這是最基本的注入方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.