2011-07-11 46 views
1

我用一些數據庫查詢構建了一個原型系統。由於它只是一個原型,而且我對數據庫非常陌生,所以我只使用了一個直接字符串。這是我使用的字符串,它工作正常:VB.NET - 在參數化查詢時遇到一些麻煩

command = New OleDbCommand("SELECT * FROM " + prefix + "CanonicForms WHERE Type=1 AND Canonic_Form='" + item + "'", dictionary_connection) 

現在,把它在實際系統中,我想用更安全的parametized方法,所以一些谷歌上搜索後,我想出了這一點:

command = New OleDbCommand("SELECT * FROM @prefix WHERE Type=1 AND [email protected]", dictionary_connection) 
command.Parameters.AddWithValue("@prefix", prefix + "CanonicForms") 
command.Parameters.AddWithValue("@form", item) 

但我得到的是一個不完整的查詢子句的錯誤。我在兩者之間做了什麼不同?

回答

3

您的表名不能是參數。你可能需要做某種形式的連接。這不是一個真正的正式意義上的參數。

+0

真的嗎?如果你有一個表格名稱取決於某種輸入,是不是會打開注入問題,就像不使用參數一樣糟糕?如果我只是使用表連接,我的意思是 – cost

+0

我會說它可以打開你。你可能想「清理」表名 - 我認爲這是很常見的。沒有人喜歡連接一個sql語句,但有時候你沒有太多的選擇。 –

+1

@cost:SQL注入是連接UNVERIFIED/sanitized輸入的結果。如果您驗證了輸入,則您不打開SQL注入。在這種情況下,驗證輸入的首選方法是將用戶輸入的內容映射到已知的表名稱(因此不直接使用用戶輸入),如果不可能,可以先驗證表名稱是否存在,然後再進行串接它(即使用針對information_schema.tables的參數化查詢)。所以,是的,它對注射是開放的​​,但它不一定非常容易被注射。 – jmoreno

1

正如ek_ny所述,您的表名稱不能是參數。

如果你真的關於注入的偏執狂,那麼在建立SQL字符串之前,先檢查表名中是否有允許值的白名單。

1

@成本,我同意它會很好,但它只是不是一個功能存在。通常假設您的WHERE子句是查詢的動態部分,其他所有內容(包括SELECT列表和表名稱)都是靜態的。實際上,大多數WHERE子句都不是動態的,只有搜索值本身。您無法以這種方式動態添加列名稱。這絕對可以建立,但它會要求查詢引擎更多地意識到數據庫引擎,這是微軟不願意開放的蠕蟲病毒罐。

想象一個下拉菜單,其中包含表格名稱,例如'Jobs','People','Employers',一些天真的開發者構建的。在回發中,該值用於SELECT * FROM。只需要簡單的SQL注入即可跳轉到該菜單中未列出的另一個表。傳遞一些非常奇怪的東西可能會很容易拋出一個可能會泄露數據庫內容的錯誤。僅限參數值的參數查詢仍然可以被破壞,但表面面積要小得多。

一些具有多個表前綴的人使用模式,這是一個選項嗎?

相關問題