梁天一
【摘要】 互聯(lián)網(wǎng)的高速發(fā)展使得網(wǎng)絡(luò)安全成為各界關(guān)注的焦點(diǎn)問題。人們把在電子商務(wù)、社交網(wǎng)絡(luò)等互聯(lián)網(wǎng)應(yīng)用中產(chǎn)生的大量重要數(shù)據(jù)存儲(chǔ)于數(shù)據(jù)庫(kù)中,而這些數(shù)據(jù)庫(kù)便成為網(wǎng)絡(luò)黑客的攻擊目標(biāo)。目前,SQL注入攻擊是網(wǎng)絡(luò)中最為猖獗的黑客攻擊行為之一。本文將詳細(xì)闡述SQL注入式攻擊的原理,并給出在Java Web應(yīng)用程序中防御SQL注入攻擊的有效方法。
【關(guān)鍵詞】 SQL注入 網(wǎng)絡(luò)安全 數(shù)據(jù)庫(kù) Java Web 防御
如今,互聯(lián)網(wǎng)已經(jīng)融入現(xiàn)代社會(huì)的方方面面,電子商務(wù)、社交網(wǎng)絡(luò)、在線教育(MOOC)已經(jīng)成為當(dāng)下人們生活不可或缺的組成。人們?cè)谑褂眠@些互聯(lián)網(wǎng)應(yīng)用時(shí),會(huì)產(chǎn)生大量與自身相關(guān)的數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中。由于這些數(shù)據(jù)的潛在價(jià)值(如個(gè)人隱私數(shù)據(jù)、網(wǎng)銀賬戶等),使得它們成為網(wǎng)絡(luò)黑客主要的攻擊目標(biāo)之一。目前,最為常見的、破壞性最強(qiáng)的針對(duì)互聯(lián)網(wǎng)應(yīng)用數(shù)據(jù)庫(kù)系統(tǒng)的攻擊方式是SQL注入攻擊。綜合統(tǒng)計(jì)資料來看,SQL注入約占據(jù)互聯(lián)網(wǎng)安全威脅性事件總數(shù)的1/3,且程逐年遞增趨勢(shì);DB Networks的統(tǒng)計(jì)表明,2014年SQL注入漏洞數(shù)量較2013年增長(zhǎng)104%[1]。因此,本文將探討、研究注入技術(shù)背后的原理、實(shí)施方法和分類,來更好的應(yīng)對(duì)這類攻擊;同時(shí)結(jié)合Java Web開發(fā)技術(shù),給出在Java Web應(yīng)用程序中防御SQL注入攻擊的有效方法。
一、SQL注入攻擊的原理
SQL注入攻擊(SQL Injection Attack, SQLI),是指利用應(yīng)用程序?qū)优c數(shù)據(jù)庫(kù)層之間的安全漏洞、通過惡意SQL語(yǔ)句攻擊這些漏洞來非法獲取目標(biāo)數(shù)據(jù)的行為。簡(jiǎn)單來說,精心設(shè)計(jì)的惡意SQL語(yǔ)句會(huì)從應(yīng)用程序前端提交至后臺(tái)數(shù)據(jù)庫(kù)執(zhí)行,執(zhí)行過程中應(yīng)用程序開發(fā)者編寫的原始SQL語(yǔ)句會(huì)被惡意語(yǔ)句篡改,從而暴露攻擊者想要獲取的隱私數(shù)據(jù)。
圖1描述了一個(gè)B/S架構(gòu)應(yīng)用程序遭受SQL注入攻擊的基本流程。假設(shè)該系統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)中存儲(chǔ)有某單位全體員工的個(gè)人信息,提交URL:
demo.com/liststaff?staff_id=13098
Web應(yīng)用服務(wù)器將獲取到參數(shù)staff_id=130
98,并在數(shù)據(jù)庫(kù)中執(zhí)行下列SQL查詢語(yǔ)句:
SELECT name, gender, age, salary, address
FROM t_staff
WHERE staff_id = ‘13098;
數(shù)據(jù)庫(kù)將返回員工ID(staff_id)為13098的員工的詳細(xì)個(gè)人詳細(xì),如姓名、收入、家庭住址等。如果攻擊者想要竊取全部員工的個(gè)人信息,針對(duì)上述SQL查詢語(yǔ)句,他可以構(gòu)造這樣一條請(qǐng)求URL:
demo.com/liststaff?staff_id=13098 or ‘1=1
那么在數(shù)據(jù)庫(kù)中將執(zhí)行下列查詢語(yǔ)句:
SELECT name, gender, age, salary, address
FROM t_staff
WHERE staff_id = ‘13098 or ‘1 = 1;
由于staff_id=‘13098 or ‘1 = 1為永真句,因此該系列語(yǔ)句等效為:
SELECT name, gender, age, salary, address
至此,攻擊者成功竊取了全部員工的個(gè)人信息。
二、Java Web程序?qū)QL注入攻擊的防御方法
盡管Java Web技術(shù)在設(shè)計(jì)之初就十分重視安全性,Java Web技術(shù)也是目前最安全的開發(fā)技術(shù)之一,但在實(shí)際開發(fā)和應(yīng)用中,使用Java Web技術(shù)構(gòu)建的應(yīng)用仍有可能受到SQL注入攻擊的破壞。本文將討論幾種在Java Web應(yīng)用中防御SQL注入攻擊的有效方法。
2.1 使用正則表達(dá)式過濾參數(shù)
從前文論述我們可以看出,SQL注入攻擊的核心在于向數(shù)據(jù)庫(kù)服務(wù)器提交含有特殊含義的字符,改變?cè)糞QL語(yǔ)句的語(yǔ)義。因此,使用正則表達(dá)式過濾掉用戶提交參數(shù)中的特殊字符(如轉(zhuǎn)義字符),便能大大降低發(fā)生注入攻擊的概率。
上述代碼中的正則表達(dá)式”.*([‘;]+|(--)+).*”可以檢測(cè)出用戶提交參數(shù)中的特殊字符(如轉(zhuǎn)義字符單引號(hào)),將其替換為空格符,防止數(shù)據(jù)庫(kù)受到注入攻擊。
public static String filterSQLInjection(String param) {
return param.replaceAll(".*([;]+|(--)+).*", "");
}
String userName = filterSQLInjection(request. getParameter(userName));
String userPasswd = filterSQLInjection(request. getParameter(userPasswd));
2.2 使用預(yù)編譯技術(shù)防止SQL注入
SQL注入攻擊能夠?qū)崿F(xiàn)的基本前提是程序員使用拼接SQL語(yǔ)句的方式編寫數(shù)據(jù)庫(kù)操作語(yǔ)句,如:
String sql = “SELECT * FROM t_admin WHERE user_ name = ” + userName + “ AND password = ” + userPasswd;
ResultSet rs = statement.executeQuery(sql);
因此,防御SQL注入攻擊的最有效方法是禁止使用拼接的方法編寫SQL語(yǔ)句,轉(zhuǎn)而使用預(yù)編譯技術(shù)進(jìn)行數(shù)據(jù)庫(kù)操縱方面的開發(fā)。
所謂預(yù)編譯,指的是將格式結(jié)構(gòu)固定的SQL語(yǔ)句編譯后,存儲(chǔ)在數(shù)據(jù)庫(kù)緩存中,當(dāng)調(diào)用該語(yǔ)句時(shí),直接執(zhí)行緩存中編譯后的結(jié)果。使用預(yù)編譯機(jī)制可以消除注入攻擊的隱患,因?yàn)镾QL語(yǔ)句已經(jīng)通過編譯,傳入的參數(shù)不會(huì)跟其發(fā)生任何匹配關(guān)系。在Java中,通過PreparedStatement類實(shí)現(xiàn)了預(yù)編譯相關(guān)功能,使用方法如下:
String sql= "SELECT * FROM t_admin WHERE user_ name=? AND password=?";
PreparedStatement psmt=conn.prepareSattement(sql);
psmt.setString(1, userName);
psmt.setString(2, userPasswd);
ResultSet rs = preState.executeQuery();
三、結(jié)束語(yǔ)
本文結(jié)合實(shí)例,論述了SQL注入攻擊的原理和實(shí)施過程,討論了SQL注入攻擊的分類和最新發(fā)展;最后,提出了Java Web應(yīng)用程序防御SQL注入的幾種有效方法,具有一定借鑒意義。
參 考 文 獻(xiàn)
[1] 王麗麗, 彭一楠, 王軼駿. 淺析SQL盲注攻擊的實(shí)現(xiàn)[J]. 信息安全與通信保密, 2008, 05期(05):71-73.