2016-11-09 80 views
0

我正在嘗試使用一些通用代碼來從表中檢索標識,並涉及到使用不安全的查詢字符串來注入表名。安全地查詢帶有變量表名稱的SQL表

我到處讀到我無法安全地注入表名。所以我想查詢表是否存在,然後根據結果執行真實或虛擬查詢。

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 

我是在我的假設是正確的,這是安全的嗎?

+0

'tableName =「Users]; drop table users; - 」' –

+0

@GiorgiNakeuri和這裏得到執行? – romeozor

+0

'cmd.ExecuteReader()'? –

回答

1

假設您的用戶有權更改變量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; 

注即使ELSE部分未執行,也會執行該drop語句,因爲您沒有BEGIN END。請注意,其餘的被註釋掉...這是最基本的注入方法...這是最基本的注入方法...

+0

爲'ELSE'塊添加'BEGIN..END'後,我運行了查詢代表生成以下內容: '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 BEGIN SELECT [Id] FROM [dbo]。[StatusTime; DROP TABLE Temp; - ] WHERE [BulkInsertSessionID] = @bulkInsertSessionId END'(並添加必要的參數),我爲此練習創建的Temp表沒有被刪除。 現在是什麼? – romeozor

+1

@romeozor,所以你想說你相信代碼是安全的嗎?這是你的決定,但它是不安全的。它沒有被丟棄,因爲它可能會引發異常。試試這個:'用戶]; END DROP TABLE Users; - ' –

+0

我什麼都沒說,我在尋求幫助。我嘗試了你以前的評論,但它仍然沒有放棄表格。 我願意接受這並不安全,但您被動地採取侵略性行爲並沒有幫助。 – romeozor