2012-11-03 53 views
2

此問題僅用於教育目的,因爲我目前沒有構建任何使用用戶輸入構建SQL查詢的應用程序。在ADO.NET中,SQL查詢中可以使用SQL參數的限制有哪些?

這麼說,我知道,在ADO.NET你可以做這樣的事情防止SQL注入:

OleDbCommand command = new OleDbCommand("SELECT * FROM Table WHERE Account = @2", connection); 
command.Parameters.AddWithValue("@2", "ABC"); 

不過,假設您的應用程序的設計是這樣一種方式,用戶可以真正進入表格的名稱,你可以做以下嗎? (我不關心,如果這是一個壞主意,讓用戶能夠提供表的名字,我只是想知道,如果以下是可能的...)

OleDbCommand command = new OleDbCommand("SELECT * FROM @1 WHERE Account = @2", connection); 
command.Parameters.AddWithValue("@1", "Table"); 
command.Parameters.AddWithValue("@2", "ABC"); 

我不斷收到一個異常時,我運行第二個代碼,說SQL查詢是不完整的,我想知道如果問題是我所做的事情根本無法完成,或者我忽略了某些事情。

+2

然後,你需要動態的SQL。 http://www.sommarskog.se/dynamic_sql.html –

回答

4

不,在您的SQL語句中,查詢參數可以代替一個標量值
例如,單個字符串文字,日期文字或數字文字。

它不必位於WHERE子句中。任何你可以在SQL中擁有表達式的地方,都可以包含一個標量值,因此也可以包含一個參數。例如,在連接條件中,或在選擇列表中,或在ORDER BY或GROUP BY子句中。

不能使用的查詢參數:

  • 表標識符
  • 列標識符
  • SQL關鍵字
  • SQL表達式的值(例如
  • 列表中的IN()謂詞)

如果您需要使用戶可定義的查詢的這些部分中的任何一部分,那麼您需要通過在應用程序變量中插入或連接字符串來構建SQL查詢字符串。這使得防禦SQL注入變得困難。

這種情況下的最佳防禦是白名單可安全插入到您的SQL字符串中的特定值,例如您在代碼中定義的一組表名。讓用戶從這些預先批准的值中選擇一個表,但不要在SQL代碼中逐字逐句輸入,然後執行。

用戶輸入可能會提供值,但不應該提供代碼。

你會發現我的介紹SQL Injection Myths and Fallacies很有幫助。我在該演示文稿中列出了白名單(我的示例使用PHP,但這個想法適用於任何編程語言)。