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