概念
SQL注入是一種欺騙數據庫服務器的攻擊手段,通過修改或拼接web界面中表單域、原URL或數據包輸入的參數為SQL語句,輸入到web服務器中進而使數據庫服務器執行數據庫命令。
簡單的說,就是在輸入字符串中嵌入SQL命令,在設計程序中忽略了對特殊字符串的檢查,這些嵌入的指令便會被誤認為是正常的SQL命令從而在數據庫中執行,從而攻擊成功。
假如一個網站的頁面顯示URL為example.com?test=111,此時URL實際向服務器傳遞了值為111的變量test,這表明當前頁面是對數據庫進行動態查詢的結果,此時在URL中插入惡意SQL語句并執行。
例如一個網站登錄驗證的 SQL 查詢代碼為:
strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ password +"');"
如果填入以下內容:
userName = "1' OR '1'='1";
passWord = "1' OR '1'='1";
那么 SQL 查詢字符串為:
strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
此時無需驗證通過就能執行以下查詢:
strSQL = "SELECT * FROM users;"
分類
目前SQL注入大致分為普通注入和盲注:
普通注入
根據后臺數據庫提示有價值的錯誤信息進行注入。
盲注
有經驗的管理員在給出代碼有漏洞的頁面時,沒有提供詳細的錯誤信息。
攻擊者需要運用腳本通過僅有的判斷信息(比如時間差)對表中的每一個字段進行探測,從而實現注入的技術(盲注的難度較大,但注入測試中經常會遇到)。
危害
只要是使用數據庫開發的應用系統就可能存在SQL注入攻擊。
自1999年起,SQL注入就成了常見安全漏洞之一,SQL注入漏洞至今仍然在CVE列表中排前十。
防范SQL注入的方法
錯誤消息處理
要防御SQL注入,就要避免在網頁中出現一些詳細的錯誤信息。
攻擊者可以利用這些信息來插入SQL語句,因此使用一種標準的輸入確認機制來驗證所有的輸入數據的類型、長度、規則、語句等。
輸入驗證
檢查用戶輸入的合法性,盡量限制用戶輸入特殊的符號,確保輸入的內容只包含合法的數據。
在客戶端和服務器端都要執行用戶輸入檢查。之所以要執行服務器端驗證,是為了彌補客戶端驗證機制脆弱的安全性。
加密處理
沒有加密的數據可以被直接利用,但是加密了就不一定會解密成功,因此盡量不要使用一些常見的加密算法,就算用也要使用32位以上的加密算法,將用戶登錄名稱、密碼等數據加密保存。
加密用戶輸入的數據,然后再將它與數據庫中保存的數據比較,這相當于對用戶輸入的數據進行了“消毒”處理,用戶輸入的數據不再對數據庫有任何特殊的意義,從而也就使攻擊者無法利用用戶輸入來注入SQL命令。
存儲過程來執行所有的查詢
SQL參數的傳遞方式將防止利用單引號和連字符實施注入。
此外,它還使得數據庫權限只允許特定的存儲過程執行,所有的用戶輸入必須遵從被調用的存儲過程,這樣就很難再發生SQL注入了。