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