在後臺發生了什麼,使得SQLParameter可以防止.NET參數化查詢中的SQL Inection攻擊?它只是剝奪了任何可疑的角色,還是有更多的東西?SQLParameter如何防止SQL注入?
有沒有人在那裏查看實際到達SQL Server時通過惡意輸入?
相關:Can you use a SQLParameter in the SQL FROM statement?
在後臺發生了什麼,使得SQLParameter可以防止.NET參數化查詢中的SQL Inection攻擊?它只是剝奪了任何可疑的角色,還是有更多的東西?SQLParameter如何防止SQL注入?
有沒有人在那裏查看實際到達SQL Server時通過惡意輸入?
相關:Can you use a SQLParameter in the SQL FROM statement?
基本上,當您執行SQLCommand
使用SQLParameters
,參數從不直接插入語句。而是調用一個名爲sp_executesql
的系統存儲過程,並給定SQL字符串和參數數組。
當這樣使用時,參數被隔離並作爲數據處理,而不必從語句中解析出來(因此可能改變它),所以參數包含的內容永遠不會被「執行」。你會得到一個很大的錯誤,即參數值在某些方面是無效的。
「參數的集合,如SqlParameterCollection提供類型檢查和長度驗證如果使用參數集合,輸入被視爲文字值,SQL Server不把它當作可執行代碼。使用參數集合的另一個好處是可以執行類型和長度檢查,範圍之外的值會觸發異常,這是深度防禦的一個好例子。「
當使用參數化查詢時,攻擊面將被減少到使用參數。
請使用SqlParameters
,但不要忘記溢出,下溢和未驗證的參數。例如,如果方法是「proc buy_book (@price money
」),則惡意攻擊者會試圖欺騙應用程序以運行@price
設置爲0.01
,或試圖讓應用程序通過提交導致溢出的內容來執行某些有趣的操作。 SQL溢出往往不是有趣的(即它們只是導致的異常,你是不太可能能夠寫入相鄰的存儲器)
一個比較容易理解的,更普遍的答案是這樣的:
想象一下,一個動態的SQL查詢:
sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password
一個簡單的SQL注入將只是把用戶名作爲' OR 1=1--
這將有效地使SQL查詢:
sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password
這是說選擇所有的客戶,他們的用戶名是空白(''
)或1=1
,這是一個布爾值,等同於真實的。然後它使用--
來註釋掉其餘的查詢。因此,這將打印出整個客戶表,或讓您隨心所欲地做任何事情。
現在,參數化查詢,採取不同的方式,用這樣的代碼:
sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)
其中用戶名和密碼是指向相關inputed用戶名和密碼的變量。
現在,在這一點上,你可能會認爲,這不會改變任何事情。當然,你仍然可以只投入了用戶名字段像沒有人OR 1 = 1' - ,有效地使查詢:
sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'
這似乎是一個有效的論據。但是,你會錯的。
方式參數化查詢工作,是SQL查詢作爲一個查詢發送,並且數據庫確切地知道這個查詢會做,然後纔將其輸入用戶名和密碼僅僅作爲值。這意味着它們不會影響查詢,因爲數據庫已經知道查詢將執行什麼操作。所以在這種情況下,它會尋找一個用戶名Nobody OR 1=1'--
和一個空白的密碼,這應該是錯誤的。
雖然這不是一個完整的解決方案,並且輸入驗證仍然需要完成,因爲這不會影響其他問題,如xss攻擊,因爲您仍然可以將JavaScript放入數據庫。然後,如果這是讀出到一個頁面上,它會顯示爲正常的JavaScript,這取決於任何輸出驗證。所以最好的做法仍然是使用輸入驗證,但使用參數化查詢或存儲過程來阻止任何SQL攻擊。
來源:http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html
您還可以得到一個錯誤的嘗試使用變量的地方SQL(和TSQL在這種情況下)不支持變量。 IE:`FROM`子句,一個參數代表一個逗號分隔的列表在`IN`條款等 – 2011-02-03 22:07:18
我不認爲這個答案。您可以使用SQLParameter類調用存儲過程,該類將params傳遞給過程,但不調用sp_executesql。連接的sql字符串中的參數值會發生什麼? – Ian 2017-09-06 15:21:29