原理很簡單:使用Global.asax中的Application_BeginRequest(object sender, EventArgs e)事件,實現表單或URL提交資料的擷取,然後通過SQLInjectionHelper類完成惡意代碼的檢查。
本代碼只是考慮到通用性和部署簡易性,因為項目已經開發完畢,並已經上線,為避免大量修改,才寫的這個通用程式,大家可以在這裡面加入不需要檢查的表單值,這樣不檢查某些欄位也是可以實現的。
直接貼代碼:
Global.ascx.cs
//在接收到一個應用程式請求時觸發。對於一個請求來說,它是第一個被觸發的事件,請求一般是使用者輸入的一個頁面請求(URL)。
void Application_BeginRequest(object sender, EventArgs e)
{
//Response.Write("通用注入檢查");
bool result = false;
if (Request.RequestType.ToUpper() == "POST")
{
result = SQLInjectionHelper.ValidUrlPostData();//Post資料檢查
}
else
{
result = SQLInjectionHelper.ValidUrlGetData();//Get資料檢查
}
if (result)
{
Response.Write("您提交的資料有惡意字元!");
Response.Write("<script>alert('您提交的資料有惡意字元!');<//script>");
Response.End();
}
}
SQLInjectionHelper.cs注入檢測輔助類
/// <summary>
/// 擷取Post的資料
/// </summary>
public static bool ValidUrlPostData()
{
bool result = false;
for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)
{
result = ValidData(HttpContext.Current.Request.Form[i].ToString());
if (result)
{
break;
}//如果檢測存在漏洞
}
return result;
}
/// <summary>
/// 擷取QueryString中的資料
/// </summary>
public static bool ValidUrlGetData()
{
bool result = false;
for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
{
result = ValidData(HttpContext.Current.Request.QueryString[i].ToString());
if (result)
{
break;
}//如果檢測存在漏洞
}
return result;
}
/// <summary>
/// 驗證是否存在注入代碼
/// </summary>
/// <param name="inputData"></param>
public static bool ValidData(string inputData)
{
//裡面定義惡意字元集合
//驗證inputData是否包含惡意集合
if (Regex.IsMatch(inputData, GetRegexString()))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 擷取Regex
/// </summary>
/// <param name="queryConditions"></param>
/// <returns></returns>
private static string GetRegexString()
{
//構造SQL的注入關鍵字符
string[] strBadChar = {"and"
,"exec"
,"insert"
,"select"
,"delete"
,"update"
,"count"
,"from"
,"drop"
,"asc"
,"char"
,"or"
//,"*"
,"%"
,";"
,":"
,"/'"
,"/""
,"-"
,"chr"
,"mid"
,"master"
,"truncate"
,"char"
,"declare"
,"SiteName"
,"net user"
,"xp_cmdshell"
,"/add"
,"exec master.dbo.xp_cmdshell"
,"net localgroup administrators"};
//構造Regex
string str_Regex = ".*(";
for (int i = 0; i < strBadChar.Length - 1; i++)
{
str_Regex += strBadChar[i] + "|";
}
str_Regex += strBadChar[strBadChar.Length - 1] + ").*";
return str_Regex;
}
測試代碼:
1 建立表單,測試Post資料
2 直接使用Response.Redirect("TestSQLInjection.aspx?Id=100&cc=200&dd=300")或構造URL參數,測試Get資料