簡體   English   中英

使用可變表名安全查詢SQL表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM