[摘 要]本文主要針對目前ASP.NET網(wǎng)站安全面臨的SQL注入攻擊來進(jìn)行分析研究,并從客戶端和服務(wù)器端兩個方面來研究如何防范SQL注入攻擊。
[關(guān)鍵詞]網(wǎng)站安全 SQL注入 防SQL注入
一、引言
隨著時(shí)代的發(fā)展,網(wǎng)路應(yīng)用的不斷深入,互聯(lián)網(wǎng)上網(wǎng)站數(shù)量以驚人的速度增加。盡管如此,網(wǎng)絡(luò)上環(huán)境的復(fù)雜性、多變性,以及信息系統(tǒng)的脆弱性,決定了現(xiàn)有的計(jì)算機(jī)系統(tǒng)還不具備與自身的應(yīng)用發(fā)展規(guī)模相對應(yīng)的安全防護(hù)能力,大量的網(wǎng)絡(luò)威脅采用各種隱蔽的方式不斷地沖擊著網(wǎng)絡(luò)應(yīng)用平臺。因此,對網(wǎng)站相關(guān)安全技術(shù)進(jìn)行研究是很有必要的。
二、防SQL注入攻擊技術(shù)的實(shí)現(xiàn)
1、SQL注入攻擊技術(shù)簡介
SQL注入攻擊是當(dāng)前網(wǎng)絡(luò)攻擊的主要手段之一,SQL注入技術(shù)在國外最早出現(xiàn)在1999年,我國在2002年后開始大量出現(xiàn)。目前還沒有一個嚴(yán)格的定義來解釋什么是SQL注入漏洞,但其本質(zhì)是攻擊者能夠利用應(yīng)用程序沒有對用戶輸入的數(shù)據(jù)進(jìn)行嚴(yán)格約束和合法性檢查等錯誤在程序中插入并執(zhí)行自己構(gòu)造的SQL語句。
例如,在在Web應(yīng)用程序的登錄驗(yàn)證程序中,一般有用戶名和密碼兩個參數(shù),當(dāng)用戶點(diǎn)擊提交按鈕時(shí),服務(wù)器端會根據(jù)用戶提交的用戶名和密碼信息來與數(shù)據(jù)庫中的用戶信息表進(jìn)行比較,如果不對用戶輸入的信息進(jìn)行任何限制,在服務(wù)器端也不對用戶提交的信息進(jìn)行任何檢查,其SQL語句就可以寫成:
string strqry = \"Select * From T_Admin where Userid='\"+name+\"' and UserPwd='\"+pwd+\"'\" ;
顯然上面這段代碼并沒有對用戶的輸入進(jìn)行任何安全性的檢查,如果數(shù)據(jù)庫是SQL Server,那么惡意用戶可以在用戶名中輸入admin’or 1=1-- ,在密碼框中輸入任何值(如:111),這樣,SQL腳本解釋器中的上述語句就會變?yōu)?
Select * From T_Admin where Userid='admin' or 1=1 -- and UserPwd='111'
由于在SQL Server數(shù)據(jù)庫中“--”表示注釋,因此“--”后面的語句都為注釋語句,這樣在兩個條件“Userid='admin'”和“1=1”中,只要任何一個成立,該語句就會執(zhí)行成功,而1=1在邏輯判斷上是恒成立的,因此不管T_Admin表中有沒有admin這個用戶,該語句都會執(zhí)行成功并錯誤地將權(quán)限授予攻擊者。
2、ASP.NET下防范SQL注入攻擊策略的實(shí)現(xiàn)
要防范SQL注入攻擊,需要對用戶輸入的數(shù)據(jù)進(jìn)行檢查,檢查可以在客戶端進(jìn)行,也可以在服務(wù)器端進(jìn)行。在客戶端,攻擊者完全有可能獲得網(wǎng)頁的源代碼,修改驗(yàn)證合法性的腳本(或者直接刪除腳本),然后將非法內(nèi)容通過修改后的表單提交給服務(wù)器。因此,要保證驗(yàn)證安全性,唯一的辦法就是在服務(wù)器端也執(zhí)行驗(yàn)證。但使用客戶端驗(yàn)證可以減少頁面往返次數(shù)以提升性能,改進(jìn)用戶體驗(yàn)。因此,在實(shí)際中往往在客戶端和服務(wù)器端同時(shí)進(jìn)行檢查。
(1)客戶端的防SQL注入功能的實(shí)現(xiàn)
在客戶端,可以JavaScript 腳本語言來編寫用于檢查用戶輸入的函數(shù),也可以通過ASP.NET提供的輸入輸入驗(yàn)證控件來檢查用戶的輸入。其中,使用ASP.NET提供的輸入驗(yàn)證控件來檢查用戶的輸入是最簡單的方法。
在ASP.NET中,RegularExpressionValidator控件是一個強(qiáng)大的工具。他可以檢驗(yàn)文本是否和定義的正則表達(dá)式中的模式匹配。你只需要簡單地配置ValidationExpression屬性的正則表達(dá)式即可。正則表達(dá)式也是一個強(qiáng)大的工具,它允許指定復(fù)雜的規(guī)則,該規(guī)則指定字符和字符順序(位置和出現(xiàn)次數(shù))。為防止用戶輸入一些危險(xiǎn)的字符,可以利用該正則表達(dá)式“^[0-9A-Za-z_]+$”,該表達(dá)式表示的意思是用戶只可以輸入字母和數(shù)字。要運(yùn)用該正則表達(dá)式,只需在將其賦值給RegularExpressionValidator控件的ValidationExpression屬性即可。
(2)服務(wù)器端的防SQL注入功能的實(shí)現(xiàn)
由于通過客戶端進(jìn)行驗(yàn)證并不能完全保證安全性,因此,為保證安全性,最有效的辦法是在服務(wù)器端進(jìn)行驗(yàn)證。在服務(wù)器端,通常的做法有兩種,一種是構(gòu)造一個專門的函數(shù)來將特殊字符和字符串過濾掉,另一種是對SQL語句使用命令參數(shù)方式。
過濾函數(shù)一般可以表示如下:
Public string ConvertSql(string inputStr)
{
inputString = inputString.Trim();
inputString = inputString.Replace(\"' \", \" \");
inputString = inputString.Replace(\"=\", \" \");
inputString = inputString.Replace(\";———\", \" \");
inputString = inputString.Replace(\"and\", \" \");
inputString = inputString.Replace(\"or\", \" \");
return inputString;
}
過濾特殊字符在asp.net中并非最有效的方式, 因?yàn)槿绻谋敬_實(shí)需要包含這些符號,這樣就引入了其他麻煩,更好的解決辦法是使用參數(shù)化命令來防止SQL注入攻擊。參數(shù)化命令是在SQL文本中使用占位符的命令。占位符表示需要動態(tài)替換的值,它們通過Command對象的Parameters集合來傳送。在管理員登陸頁面,如果使用參數(shù)化命令,其SQL語句就可以表示為:
Select * From T_Admin where Userid=@name and UserPwd=@pwd
在該SQL語句中@name和@pwd是參數(shù)的名字,所有參數(shù)必須以@字符開頭。使用參數(shù)化命令后,當(dāng)惡意用戶在用戶名中輸入admin’or 1=1--時(shí),應(yīng)用程序就會從T_Admin表中檢索用戶名為admin’or 1=1--的用戶,顯然這樣就不可能得到任何記錄,因?yàn)闆]有一個管理員的用戶名是admin’or 1=1--。參數(shù)化命令的實(shí)現(xiàn)可表示如下。
//使用參數(shù)化命令申明SQL語句
string mysql = \"Select * From T_Admin where Userid=@name and UserPwd=@pwd\";
OleDbConnection conn = new OleDbConnection(connStr );
OleDbCommand cmd = new OleDbCommand(mysql, conn);
//對@name參數(shù)賦值
cmd.Parameters.AddWithValue(\"@name\", name);
//對@password參數(shù)賦值
cmd.Parameters.AddWithValue(\"@pwd\", Password);
參考文獻(xiàn):
[1]David Litchfield,Chris Anley.The database hacker's handbook[M].Wiley Publishing Inc,2005
[2]陳小兵,張漢煜,駱力明,黃河 . SQL注入攻擊及其防范檢測技術(shù)研究[J] . 計(jì)算機(jī)工程與應(yīng)用 , 2007,43(11)
[3]Bass L,Clements P,Kazman R.Software Architecture in practice[M].北京:清華大學(xué)出版社,2003:71-127