SQL注入攻擊的危害性很(hěn)大(dà)。在講解其防止辦法之前,數(shù)據庫管理(lǐ)員有(yǒu)必要先了解一下其攻擊的原理(lǐ)。這有(yǒu)利于管理(lǐ)員采取有(yǒu)針對性的防治措施。
一、 SQL注入攻擊的簡單示例。
statement := "SELECT * FROM Users WHERE Value= " + a_variable + "
上(shàng)面這條語句是很(hěn)普通(tōng)的一條SQL語句,他主要實現的功能就是讓用戶輸入一個(gè)員工編号然後查詢處這個(gè)員工的信息。但(dàn)是若這條語句被不法攻擊者改裝過後,就可(kě)能成為(wèi)破壞數(shù)據的黑(hēi)手。如攻擊者在輸入變量的時(shí)候,輸入以下內(nèi)容SA001’;drop table c_order--。那(nà)麽以上(shàng)這條SQL語句在執行(xíng)的時(shí)候就變為(wèi)了SELECT * FROM Users WHERE Value= ‘SA001’;drop table c_order--。
這條語句是什麽意思呢?‘SA001’後面的分号表示一個(gè)查詢的結束和(hé)另一條語句的開(kāi)始。c_order後面的雙連字符指示當前行(xíng)餘下的部分隻是一個(gè)注釋,應該忽略。如果修改後的代碼語法正确,則服務器(qì)将執行(xíng)該代碼。系統在處理(lǐ)這條語句時(shí),将首先執行(xíng)查詢語句,查到用戶編号為(wèi)SA001 的用戶信息。然後,數(shù)據将删除表C_ORDER(如果沒有(yǒu)其他主鍵等相關約束,則删除操作(zuò)就會(huì)成功)。隻要注入的SQL代碼語法正确,便無法采用編程方式來(lái)檢測篡改。因此,必須驗證所有(yǒu)用戶輸入,并仔細檢查在您所用的服務器(qì)中執行(xíng)構造 SQL命令的代碼。
二、 SQL注入攻擊原理(lǐ)。
可(kě)見SQL注入攻擊的危害性很(hěn)大(dà)。在講解其防止辦法之前,數(shù)據庫管理(lǐ)員有(yǒu)必要先了解一下其攻擊的原理(lǐ)。這有(yǒu)利于管理(lǐ)員采取有(yǒu)針對性的防治措施。
SQL注入是目前比較常見的針對數(shù)據庫的一種攻擊方式。在這種攻擊方式中,攻擊者會(huì)将一些(xiē)惡意代碼插入到字符串中。然後會(huì)通(tōng)過各種手段将該字符串傳遞到SQLServer數(shù)據庫的實例中進行(xíng)分析和(hé)執行(xíng)。隻要這個(gè)惡意代碼符合SQL語句的規則,則在代碼編譯與執行(xíng)的時(shí)候,就不會(huì)被系統所發現。
SQL注入式攻擊的主要形式有(yǒu)兩種。一是直接将代碼插入到與SQL命令串聯在一起并使得(de)其以執行(xíng)的用戶輸入變量。上(shàng)面筆者舉的例子就是采用了這種方法。由于其直接與SQL語句捆綁,故也被稱為(wèi)直接注入式攻擊法。二是一種間(jiān)接的攻擊方法,它将惡意代碼注入要在表中存儲或者作(zuò)為(wèi)原書(shū)據存儲的字符串。在存儲的字符串中會(huì)連接到一個(gè)動态的SQL命令中,以執行(xíng)一些(xiē)惡意的SQL代碼。
注入過程的工作(zuò)方式是提前終止文本字符串,然後追加一個(gè)新的命令。如以直接注入式攻擊為(wèi)例。就是在用戶輸入變量的時(shí)候,先用一個(gè)分号結束當前的語句。然後再插入一個(gè)惡意SQL語句即可(kě)。由于插入的命令可(kě)能在執行(xíng)前追加其他字符串,因此攻擊者常常用注釋标記“—”來(lái)終止注入的字符串。執行(xíng)時(shí),系統會(huì)認為(wèi)此後語句位注釋,故後續的文本将被忽略,不背編譯與執行(xíng)。
三、 SQL注入式攻擊的防治。
既然SQL注入式攻擊的危害這麽大(dà),那(nà)麽該如何來(lái)防治呢?下面這些(xiē)建議或許對數(shù)據庫管理(lǐ)員防治SQL注入式攻擊有(yǒu)一定的幫助。
1、普通(tōng)用戶與系統管理(lǐ)員用戶的權限要有(yǒu)嚴格的區(qū)分。
如果一個(gè)普通(tōng)用戶在使用查詢語句中嵌入另一個(gè)Drop Table語句,那(nà)麽是否允許執行(xíng)呢?由于Drop語句關系到數(shù)據庫的基本對象,故要操作(zuò)這個(gè)語句用戶必須有(yǒu)相關的權限。在權限設計(jì)中,對于終端用戶,即應用軟件的使用者,沒有(yǒu)必要給他們數(shù)據庫對象的建立、删除等權限。那(nà)麽即使在他們使用SQL語句中帶有(yǒu)嵌入式的惡意代碼,由于其用戶權限的限制(zhì),這些(xiē)代碼也将無法被執行(xíng)。故應用程序在設計(jì)的時(shí)候,最好把系統管理(lǐ)員的用戶與普通(tōng)用戶區(qū)分開(kāi)來(lái)。如此可(kě)以最大(dà)限度的減少(shǎo)注入式攻擊對數(shù)據庫帶來(lái)的危害。
2、強迫使用參數(shù)化語句。
如果在編寫SQL語句的時(shí)候,用戶輸入的變量不是直接嵌入到SQL語句。而是通(tōng)過參數(shù)來(lái)傳遞這個(gè)變量的話(huà),那(nà)麽就可(kě)以有(yǒu)效的防治SQL注入式攻擊。也就是說,用戶的輸入絕對不能夠直接被嵌入到SQL語句中。與此相反,用戶的輸入的內(nèi)容必須進行(xíng)過濾,或者使用參數(shù)化的語句來(lái)傳遞用戶輸入的變量。參數(shù)化的語句使用參數(shù)而不是将用戶輸入變量嵌入到SQL語句中。采用這種措施,可(kě)以杜絕大(dà)部分的SQL注入式攻擊。不過可(kě)惜的是,現在支持參數(shù)化語句的數(shù)據庫引擎并不多(duō)。不過數(shù)據庫工程師(shī)在開(kāi)發産品的時(shí)候要盡量采用參數(shù)化語句。
3、加強對用戶輸入的驗證。
總體(tǐ)來(lái)說,防治SQL注入式攻擊可(kě)以采用兩種方法,一是加強對用戶輸入內(nèi)容的檢查與驗證;二是強迫使用參數(shù)化語句來(lái)傳遞用戶輸入的內(nèi)容。在SQLServer數(shù)據庫中,有(yǒu)比較多(duō)的用戶輸入內(nèi)容驗證工具,可(kě)以幫助管理(lǐ)員來(lái)對付SQL注入式攻擊。測試字符串變量的內(nèi)容,隻接受所需的值。拒絕包含二進制(zhì)數(shù)據、轉義序列和(hé)注釋字符的輸入內(nèi)容。這有(yǒu)助于防止腳本注入,防止某些(xiē)緩沖區(qū)溢出攻擊。測試用戶輸入內(nèi)容的大(dà)小(xiǎo)和(hé)數(shù)據類型,強制(zhì)執行(xíng)适當的限制(zhì)與轉換。這即有(yǒu)助于防止有(yǒu)意造成的緩沖區(qū)溢出,對于防治注入式攻擊有(yǒu)比較明(míng)顯的效果。
如可(kě)以使用存儲過程來(lái)驗證用戶的輸入。利用存儲過程可(kě)以實現對用戶輸入變量的過濾,如拒絕一些(xiē)特殊的符号。如以上(shàng)那(nà)個(gè)惡意代碼中,隻要存儲過程把那(nà)個(gè)分号過濾掉,那(nà)麽這個(gè)惡意代碼也就沒有(yǒu)用武之地了。在執行(xíng)SQL語句之前,可(kě)以通(tōng)過數(shù)據庫的存儲過程,來(lái)拒絕接納一些(xiē)特殊的符号。在不影(yǐng)響數(shù)據庫應用的前提下,應該讓數(shù)據庫拒絕包含以下字符的輸入。如分号分隔符,它是SQL注入式攻擊的主要幫兇。如注釋分隔符。注釋隻有(yǒu)在數(shù)據設計(jì)的時(shí)候用的到。一般用戶的查詢語句中沒有(yǒu)必要注釋的內(nèi)容,故可(kě)以直接把他拒絕掉,通(tōng)常情況下這麽做(zuò)不會(huì)發生(shēng)意外損失。把以上(shàng)這些(xiē)特殊符号拒絕掉,那(nà)麽即使在SQL語句中嵌入了惡意代碼,他們也将毫無作(zuò)為(wèi)。
故始終通(tōng)過測試類型、長度、格式和(hé)範圍來(lái)驗證用戶輸入,過濾用戶輸入的內(nèi)容。這是防止SQL注入式攻擊的常見并且行(xíng)之有(yǒu)效的措施。
4、多(duō)多(duō)使用SQL Server數(shù)據庫自帶的安全參數(shù)。
為(wèi)了減少(shǎo)注入式攻擊對于SQL Server數(shù)據庫的不良影(yǐng)響,在SQLServer數(shù)據庫專門(mén)設計(jì)了相對安全的SQL參數(shù)。在數(shù)據庫設計(jì)過程中,工程師(shī)要盡量采用這些(xiē)參數(shù)來(lái)杜絕惡意的SQL注入式攻擊。
如在SQL Server數(shù)據庫中提供了Parameters集合。這個(gè)集合提供了類型檢查和(hé)長度驗證的功能。如果管理(lǐ)員采用了Parameters這個(gè)集合的話(huà),則用戶輸入的內(nèi)容将被視(shì)為(wèi)字符值而不是可(kě)執行(xíng)代碼。即使用戶輸入的內(nèi)容中含有(yǒu)可(kě)執行(xíng)代碼,則數(shù)據庫也會(huì)過濾掉。因為(wèi)此時(shí)數(shù)據庫隻把它當作(zuò)普通(tōng)的字符來(lái)處理(lǐ)。使用Parameters集合的另外一個(gè)優點是可(kě)以強制(zhì)執行(xíng)類型和(hé)長度檢查,範圍以外的值将觸發異常。如果用戶輸入的值不符合指定的類型與長度約束,就會(huì)發生(shēng)異常,并報告給管理(lǐ)員。如上(shàng)面這個(gè)案例中,如果員工編号定義的數(shù)據類型為(wèi)字符串型,長度為(wèi)10個(gè)字符。而用戶輸入的內(nèi)容雖然也是字符類型的數(shù)據,但(dàn)是其長度達到了20個(gè)字符。則此時(shí)就會(huì)引發異常,因為(wèi)用戶輸入的內(nèi)容長度超過了數(shù)據庫字段長度的限制(zhì)。
5、多(duō)層環境如何防治SQL注入式攻擊?
在多(duō)層應用環境中,用戶輸入的所有(yǒu)數(shù)據都應該在驗證之後才能被允許進入到可(kě)信區(qū)域。未通(tōng)過驗證過程的數(shù)據應被數(shù)據庫拒絕,并向上(shàng)一層返回一個(gè)錯誤信息。實現多(duō)層驗證。對無目的的惡意用戶采取的預防措施,對堅定的攻擊者可(kě)能無效。更好的做(zuò)法是在用戶界面和(hé)所有(yǒu)跨信任邊界的後續點上(shàng)驗證輸入。如在客戶端應用程序中驗證數(shù)據可(kě)以防止簡單的腳本注入。但(dàn)是,如果下一層認為(wèi)其輸入已通(tōng)過驗證,則任何可(kě)以繞過客戶端的惡意用戶就可(kě)以不受限制(zhì)地訪問系統。故對于多(duō)層應用環境,在防止注入式攻擊的時(shí)候,需要各層一起努力,在客戶端與數(shù)據庫端都要采用相應的措施來(lái)防治SQL語句的注入式攻擊。
6、必要的情況下使用專業的漏洞掃描工具來(lái)尋找可(kě)能被攻擊的點。
使用專業的漏洞掃描工具,可(kě)以幫助管理(lǐ)員來(lái)尋找可(kě)能被SQL注入式攻擊的點。不過漏洞掃描工具隻能發現攻擊點,而不能夠主動起到防禦SQL注入攻擊的作(zuò)用。當然這個(gè)工具也經常被攻擊者拿(ná)來(lái)使用。如攻擊者可(kě)以利用這個(gè)工具自動搜索攻擊目标并實施攻擊。為(wèi)此在必要的情況下,企業應當投資于一些(xiē)專業的漏洞掃描工具。一個(gè)完善的漏洞掃描程序不同于網絡掃描程序,它專門(mén)查找數(shù)據庫中的SQL注入式漏洞。最新的漏洞掃描程序可(kě)以查找最新發現的漏洞。所以憑借專業的工具,可(kě)以幫助管理(lǐ)員發現SQL注入式漏洞,并提醒管理(lǐ)員采取積極的措施來(lái)預防SQL注入式攻擊。如果攻擊者能夠發現的SQL注入式漏洞數(shù)據庫管理(lǐ)員都發現了并采取了積極的措施堵住漏洞,那(nà)麽攻擊者也就無從下手了。
如沒特殊注明(míng),文章均為(wèi)中技(jì)互聯原創,轉載請(qǐng)注明(míng)來(lái)自www.zjcoo.com