2013-01-02 135 views
2

我在使用C#中的OdbcConnection對odbc驅動程序執行參數化sql查詢時遇到問題。所以我想它免受注射OdbcCommand。使用表名進行參數化

using (OdbcCommand command = connection.CreateCommand()) 
{ 
    command.CommandText = "SELECT ? FROM ?"; 
    command.CommandTimeout = SynchTimeout; 
    command.CommandType = CommandType.Text; 

    command.Parameters.Add(new OdbcParameter(string.Empty, "User")); 
    command.Parameters.Add(new OdbcParameter(string.Empty, "TableName")); 

    OdbcDataReader reader = command.ExecuteReader(); 
    while (reader.Read()) 
    { 
     // TODO: Do something clever.. 
    } 
} 

使用odcparameters爲columname「用戶」似乎確定 列名和表名將會從Web GUI配置。但如果我添加表名作爲參數與佔位符'?' 我收到以下錯誤: 錯誤[HY000] [Microsoft] [ODBC Excel驅動程序]參數'Pa_RaM002'指定需要表名稱的位置。

有沒有人知道如何傳遞一個表名安全在這種情況下,如果它不能是一個OdbcParameter?

+1

Jet/ACE驅動程序不能有表參數。 – Fionnuala

回答

1

我不認爲有可能參數化SQL中的表名和列名。所以,以某種方式,您仍然會使用字符串連接來構建動態SQL語句。

雖然在執行語句之前可能會做一些檢查。我看到兩種類型的檢查,你可以執行:

1.白名單檢查(更好的解決方案)

如果可能的話,有你允許以這種方式使用的表和列的列表。當用戶指定表和列時,請確保只允許列表中的元素。

2.動態檢查(有風險的解決方案)

應用僅在表/列的名字沒有事先(例如:動態創建的)知道這個方法,這是不可能建立一個白名單。否則,請進入白名單方法。

您可以檢查配置的表和列是否存在於數據庫中。

例如,如果您正在使用SQL Server,你可以通過查詢the Information Schema views做到這一點,就像這樣:

select top 1 COLUMN_NAME 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME = @tableNameParameter 
and COLUMN_NAME = @columnNameParameter 
and <additional criteria*> 

爲了避免運行檢查過於頻繁,你可以在網絡驗證執行這些檢查頁面,允許配置表格和列名稱。

* 警告:如果您只驗證表和列的存在,這將使用戶能夠發現數據庫中的所有表。爲了避免這種情況,你可以在你的SQL中添加一個額外的標準,以確保你只選擇那些以這種方式使用的表。例如,所有動態表可能有一定的前綴,所以你可以做[...] and TABLE_NAME like 'prefix%'


無論您選擇哪種解決方案的,要知道,這是從安全角度考慮的關鍵。您應該非常小心繫統的哪些組件可以寫入自定義表格/列值,並在每個這些點中應用驗證。

+0

很好的回答和建議。白名單是安全地做到這一點的唯一方法 – Greg

+0

@Greg感謝您的讚賞。我編輯了我的答案,強調了更多白名單方法的重要性。 – GolfWolf

+0

謝謝你的迴應!它解釋了很多! – user1943197

相關問題