金鑫 衛(wèi)文學(xué)
摘要:SQL注入是目前Web應(yīng)用程序攻擊中最常見的一種攻擊手段,但沒有一種防御方法可以防止全部類型的SQL注入攻擊。文章結(jié)合實(shí)例對SQL注入攻擊進(jìn)行簡單介紹并對其進(jìn)行分類,總結(jié)目前常用的防御方法。最后,文章提出數(shù)據(jù)加密防止SQL注入攻擊的方法,通過加密算法加密數(shù)據(jù)庫數(shù)據(jù)和所有用戶輸入,改變用戶輸入的原意進(jìn)行防御,并給出實(shí)際應(yīng)用中防止SQL注入攻擊的建議。
關(guān)鍵詞:SQL注入;數(shù)據(jù)庫;參數(shù);前臺;后臺
中圖分類號:TP393.08 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2015)20-0004-02
SQL Injection Attack and Prevention
JIN Xin1, WEI Wen-xue2
(School of Information Science and Engineering, Qingdao 266590, China)
Abstract: SQL injection is one of the most common attacks in Web application attacks, but there is no defense against all types of SQL injection attacks. This paper briefly introduces the SQL injection attacks and classifies them into a practical example, it summarizes the commonly used methods of defense. Finally, the article proposes the method of data encryption to prevent SQL injection attack, through the encryption algorithm to encrypt the database data and all user input, to change the original intent of the user input, and gives the practical application to prevent SQL injection attacks.
Key words:SQL injection; database; parameter; foreground; background
1 引言
隨著計(jì)算機(jī)和互聯(lián)網(wǎng)技術(shù)的發(fā)展,計(jì)算機(jī)網(wǎng)絡(luò)服務(wù)趨于多樣化,Web應(yīng)用程序日益流行。然而由于互聯(lián)網(wǎng)的開放性以及部分程序員的能力和經(jīng)驗(yàn)缺失,Web應(yīng)用程序又經(jīng)常存在安全問題,Web數(shù)據(jù)庫容易受到攻擊。Web應(yīng)用程序數(shù)據(jù)庫的安全問題已經(jīng)成為網(wǎng)絡(luò)安全亟待解決的問題之一,而SQL注入攻擊是Web應(yīng)用程序攻擊中最常見的一種。
2 SQL注入攻擊簡介
SQL注入是一種通過SQL代碼嵌入到Web應(yīng)用程序輸入的參數(shù)中,然后將這些參數(shù)與后臺SQL命令進(jìn)行拼接,并最終在SQL數(shù)據(jù)庫進(jìn)行解析、執(zhí)行的攻擊。
2.1 SQL注入攻擊過程
攻擊者進(jìn)行SQL注入攻擊首先要確定Web應(yīng)用程序中是否添加了驗(yàn)證,是否能夠注入,這一過程就是尋找注入點(diǎn)的過程。這一過程中一般可以通過插入單引號、插入延遲命令或者使用注入工具等方法確定注入點(diǎn)。確定注入點(diǎn)后攻擊者會在Web應(yīng)用程序前臺插入?yún)?shù),待參數(shù)傳遞到后臺后與程序中的SQL語句拼接成一條或多條新的SQL語句。新的SQL語句會經(jīng)程序處理后提交的數(shù)據(jù)庫進(jìn)行編譯并執(zhí)行,從而引發(fā)SQL注入攻擊。一般來說攻擊者攻擊Web應(yīng)用主要是為了獲取數(shù)據(jù),這時(shí)數(shù)據(jù)庫會將數(shù)據(jù)返回到前臺展示,造成信息泄露。極少數(shù)特別惡劣的攻擊會刪除數(shù)據(jù)表甚至摧毀整個(gè)數(shù)據(jù)庫,導(dǎo)致Web應(yīng)用程序丟失數(shù)據(jù)。SQL注入攻擊過程如圖1 SQL注入過程所示。
圖1 SQL注入過程
2.2 SQL注入攻擊簡單實(shí)例
一般的WEB應(yīng)用程序前臺登陸頁面包括用戶名、密碼和驗(yàn)證碼。用戶輸入用戶名、密碼和驗(yàn)證碼后點(diǎn)擊登陸,輸入的數(shù)據(jù)會傳到后臺與已經(jīng)編寫的SQL語句拼接,最后數(shù)據(jù)庫執(zhí)行SQL語句查詢此用戶信息。假設(shè)后臺已編寫的SQL語句為select * from user where username=xxx and password=xxx,并且程序沒有添加驗(yàn)證,在前臺用戶名傳參已知的用戶Y,密碼傳參Y or ‘1 =1,則前臺參數(shù)與后臺已編寫SQL語句拼接為select * from user where username= Y and password= Y or ‘1 =1。 新的SQL語句在數(shù)據(jù)庫執(zhí)行后會返回Y用戶的所有信息,并成功登陸Web應(yīng)用程序。
3 SQL注入攻擊常見的類型
3.1 字符串內(nèi)聯(lián)注入
字符串內(nèi)聯(lián)注入是指查詢的參數(shù)類型為字符串類型,在前臺注入一些SQL代碼后,原查詢?nèi)匀蝗繄?zhí)行。通常,該查詢的格式如下:select * from admin where username = ‘xxx and password = ‘xxx。
字符串類型的查詢可以通過在前臺輸入單引號來確認(rèn)是否存在注入點(diǎn),確認(rèn)存在注入點(diǎn)后在前臺輸入?yún)?shù)傳到后臺拼接SQL語句完成注入攻擊。例如,在上面的SQL語句的username處輸入一個(gè)單引號,那么SQL語句將變?yōu)閟elect * from admin where username = ‘ and password = ‘。顯然,SQL語句出現(xiàn)了語法錯(cuò)誤,如果前臺未進(jìn)行錯(cuò)誤處理,將會直接返回SQL語法錯(cuò)誤到前臺頁面。確認(rèn)此注入點(diǎn)后要做的就是在前臺輸入?yún)?shù),字符串內(nèi)聯(lián)注入時(shí)輸入的參數(shù)中一般包含一個(gè)永真條件和SQL關(guān)鍵字“or”。這里與SQL注入攻擊簡單實(shí)例類似,可以查詢已知用戶的所有信息,也可以在username和password處都輸入Y or ‘1 =1,查詢所有用戶的所有信息。
3.2 數(shù)字值內(nèi)聯(lián)注入
數(shù)字值內(nèi)聯(lián)注入與字符串內(nèi)聯(lián)注入類似,是指查詢的參數(shù)類型為數(shù)字值類型,在前臺注入一些SQL代碼后,原查詢?nèi)匀蝗繄?zhí)行。通常,該查詢的格式如下:select * from messages where id = xxx。
數(shù)字值類型的查詢確認(rèn)注入點(diǎn)的過程與字符串類型的查詢確認(rèn)注入點(diǎn)的過程相同。與字符串內(nèi)聯(lián)注入類似,確認(rèn)注入點(diǎn)后,數(shù)字值內(nèi)聯(lián)注入在前臺輸入的參數(shù)也一般包含一個(gè)永真條件和SQL關(guān)鍵字“or”。在上面的SQL語句的id處輸入1 or 1=1,查詢id為1的消息的所有信息。
3.3 終止式注入
終止式注入是指在注入SQL代碼時(shí),通過注釋剩下的查詢來成功結(jié)束該語句。終止式注入一般用在包含在多個(gè)參數(shù)的查詢中,通過保證注釋字符前面的成立,忽略注釋后面的語句來實(shí)現(xiàn)注入。例如,在 SQL注入攻擊簡單實(shí)例的SQL語句username傳參admin or ‘1=‘1--,password隨便傳值x,SQL語句變?yōu)閟elect * from admin where username = ‘a(chǎn)dmin or ‘1=‘1-- and password = ‘x。顯然,SQL語句有效部分變?yōu)閟elect * from admin where username = ‘a(chǎn)dmin,即知道用戶名即可獲取該用戶的所有信息并登錄系統(tǒng)。
3.4 執(zhí)行多條語句注入
執(zhí)行多條語句注入是指終止一條SQL語句,創(chuàng)建一條全新的沒有限制的語句。執(zhí)行多條語句注入多用在破壞數(shù)據(jù)庫系統(tǒng)。例如,假設(shè)知道user表存放登陸名和密碼,后臺SQL語句為select * from messages where id = x,攻擊者在前臺傳參1 or 1=1;delete user,則新的SQL為select * from messages where id = 1 or 1=1;delete user。顯然,一條SQL語句變?yōu)閮蓷lSQL語句,分號前面的語句是可執(zhí)行的,而分號后面的語句具有很大破壞性,直接刪除了整個(gè)user表。
4 SQL注入攻擊常見的防御方法
4.1 前臺輸入驗(yàn)證
前臺輸入驗(yàn)證是對接收的參數(shù)進(jìn)行檢查,最大限度的保證符合定義的標(biāo)準(zhǔn)的過程。前臺輸入驗(yàn)證的理念是不相信用戶輸入,檢查每個(gè)用戶輸入是否滿足預(yù)設(shè)定的類型、長度或大小、數(shù)值范圍和格式等。前臺輸入驗(yàn)證時(shí)可以使用只接受已記錄在案的良好的輸入的操作的白名單驗(yàn)證方法,也可以使用只拒絕已記錄在案的不良輸入的集合的黑名單驗(yàn)證方法。對于存在賦值輸入情況或難以確定所有可能的額輸入集合時(shí),白名單驗(yàn)證比較困難;黑名單驗(yàn)證缺點(diǎn)是潛在的不良字符列表非常大,檢索慢且不完全,并且很難及時(shí)更新。
4.2 后臺輸出驗(yàn)證
后臺輸出驗(yàn)證是對發(fā)往數(shù)據(jù)庫的內(nèi)容進(jìn)行檢查,通常是進(jìn)行通配符的替換。以SQL Server為例,由于使用單引號作為字符串的結(jié)束符,所以要對包含在字符串中的單引號進(jìn)行編碼。假設(shè)后臺SQL語句為select * from users where username=UN and password=‘PW,令UN取值已知的admin,PW取值1 or ‘1=‘1。顯然,如果直接將新的SQL語句發(fā)往數(shù)據(jù)庫會注入成功。這里添加后臺輸出驗(yàn)證,令PW = PW.replace(“ ”, “ “ ”),將字符串中的單引號替換為雙引號,那么傳到數(shù)據(jù)庫的SQL語句將變?yōu)閟elect * from users where username=admin and password= ‘1 or “1”=“1”,從而避免了注入的發(fā)生。
4.3 編碼規(guī)范化
編碼規(guī)范化是指拒絕所有不符合規(guī)范格式的輸入。有時(shí),攻擊者會在將前臺輸入發(fā)送給后臺之前對其進(jìn)行編碼,如果攻擊者所用的編碼格式恰巧與后臺編碼格式相同,則后臺對前臺輸入進(jìn)行解碼后與已編寫SQL語句拼接完成注入攻擊。例如,%27是單引號的URL編碼表示,%u0027是單引號的Unicode編碼表示,這兩種編碼表示很容易繞過前臺對單引號的輸入驗(yàn)證,如果后臺符合他們依賴的編碼規(guī)范則又會被解釋成“”。
4.4 SQL語句參數(shù)化
SQL語句參數(shù)化是指用占位符或綁定變量來向SQL查詢提供參數(shù)的方法,是一種更加安全的動態(tài)字符串構(gòu)造方法。Java、C#和PHP等語言都提供了參數(shù)化的類或方法。參數(shù)化方法可以防御絕大部分的SQL注入攻擊,因?yàn)閰?shù)化查詢可以重用執(zhí)行計(jì)劃,SQL語句所要表達(dá)的語義不會改變。然而,SQL語句參數(shù)化也有缺點(diǎn),它只能參數(shù)化數(shù)據(jù)值,不能參數(shù)化標(biāo)識符或關(guān)鍵字。例如,select * from ? where username=‘un 和select * from user where username like ‘j% order by ?這兩條語句的格式就是錯(cuò)誤的。
5 通過數(shù)據(jù)加密防止SQL注入攻擊
用戶的輸入是SQL注入攻擊的根源,所以常用的防御方法的原則是不相信用戶輸入,對用戶的輸入在前臺、后臺和數(shù)據(jù)庫進(jìn)行檢查和修改。通過數(shù)據(jù)加密防止SQL注入的方法也是基于不相信用戶輸入這一原則,將所有用戶輸入都進(jìn)行加密。
當(dāng)前臺輸入要保存到數(shù)據(jù)庫時(shí),后臺會將用戶輸入進(jìn)行加密然后直接保存到數(shù)據(jù)庫,不再解密到前臺輸入的狀態(tài);當(dāng)前臺請求查詢時(shí),后臺會將用戶輸入進(jìn)行加密然后直接到數(shù)據(jù)庫中查詢,同樣不進(jìn)行解密,當(dāng)從數(shù)據(jù)庫中返回查詢結(jié)果到后臺時(shí)再對數(shù)據(jù)進(jìn)行解密,最終返回到前臺頁面。需要強(qiáng)調(diào)的是,數(shù)據(jù)庫中保存的數(shù)據(jù)都是經(jīng)過加密的數(shù)據(jù)。
通過數(shù)據(jù)加密,攻擊者在前臺輸入的要攻擊應(yīng)用程序的參數(shù)就會改變原意。例如,在 SQL注入攻擊簡單實(shí)例的SQL語句select * from user where username=xxx and password=xxx中的username處傳參1,password處傳參1 or ‘1 =1,則SQL注入成功。然而通過凱撒密碼的加密,1加密為2,1 or ‘1 =1加密為2<!ps!<2<><2,SQL注入失敗。本例中的加密算法較為簡單,實(shí)際應(yīng)用時(shí)可選擇任意的可逆加密算法,而且一個(gè)應(yīng)用程序中可以使用多種加密算法。
6 總結(jié)
采用數(shù)據(jù)加密防止SQL注入攻擊的方法優(yōu)點(diǎn)是安全度高,攻擊者注入成功的概率和用戶隨便輸入注入成功的概率相同;缺點(diǎn)較為明顯,因加密解密過程導(dǎo)致應(yīng)用程序效率低。
實(shí)際上,由于SQL注入攻擊的種類繁多,靈活多變,很難有一種方法解決全部SQL注入問題。SQL語句參數(shù)化方法可以解決絕大多數(shù)的SQL注入問題,而參數(shù)化方法不能應(yīng)用的地方可以再采用數(shù)據(jù)加密防止SQL注入攻擊的方法,這樣既可以提高效率,又能保證應(yīng)用程序安全性。
參考文獻(xiàn):
[1]徐壽懷,胡美琛. 數(shù)據(jù)庫安全研究的現(xiàn)狀與問題[J]. 計(jì)算機(jī)工程,1997(3):50-53.
[2]高洪濤. SQL注入攻擊途徑及策略分析[J]. 網(wǎng)絡(luò)安全技術(shù)與應(yīng)用,2011(3):14-16.
[3]薛昱春,黃東. 一種新的SQL注入攻擊的防范方法[J]. 電腦知識與技術(shù),2006(2):121-122.
[4] Justin Clarke .SQL注入攻擊與防御[M] .北京:清華大學(xué)出版社,2010(6):46-57,270-292.
[5]張卓. SQL注入攻擊技術(shù)及防范措施研究[D].上海交通大學(xué),2007.5-6
[6]張勇,李力,薛倩. Web環(huán)境下SQL注入攻擊的檢測與防御[J]. 現(xiàn)代電子技術(shù),2004(15):103-105.
[7]徐書欣,王希軍. Web頁面中SQL注入攻擊過程及防御措施[J]. 信息技術(shù),2014(8):187-189.
[8]隋勵(lì)麗,張恒博. 基于參數(shù)查詢防止SQL注入攻擊的方法[J]. 大連民族學(xué)院學(xué)報(bào),2012(5):495-497.