.Net防sql注入的方法總結
#防sql注入的常用方法:
1、服務端對前端傳過來的引數值進行型別驗證;
2、服務端執行sql,使用引數化傳值,而不要使用sql字串拼接;
3、服務端對前端傳過來的資料進行sql關鍵詞過來與檢測;
#著重記錄下服務端進行sql關鍵詞檢測:
1、sql關鍵詞檢測類:
1 public class SqlInjectHelper:System.Web.UI.Page 2 { 3 private static string StrKeyWord = "select|insert|delete|from|count(|drop table|update|truncate|asc(|mid(|char(|xp_cmdshell|exec|master|net local group administrators|net user|or|and"; 4 private static string StrSymbol = ";|(|)|[|]|{|}|%|@|*|'|!"; 5 6 private HttpRequest request; 7 public SqlInjectHelper(System.Web.HttpRequest _request) 8 { 9 this.request = _request; 10 } 11 public bool CheckSqlInject() 12 { 13 return CheckRequestQuery() || CheckRequestForm(); 14 } 15 16 ///<summary> 17 ///檢查URL中是否包含Sql注入 18 /// <param name="_request">當前HttpRequest物件</param> 19 /// <returns>如果包含sql注入關鍵字,返回:true;否則返回:false</returns> 20 ///</summary> 21 public bool CheckRequestQuery() 22 { 23 if (request.QueryString.Count > 0) 24 { 25 foreach (string sqlParam in this.request.QueryString) 26 { 27 if (sqlParam == "__VIEWSTATE") 28 continue; 29 if (sqlParam == "__EVENTVALIDATION") 30 continue; 31 if (CheckKeyWord(request.QueryString[sqlParam].ToLower())) 32 { 33 return true; 34 } 35 } 36 } 37 return false; 38 } 39 ///<summary> 40 ///檢查提交的表單中是否包含Sql注入關鍵字 41 /// <param name="_request">當前HttpRequest物件</param> 42 /// <returns>如果包含sql注入關鍵字,返回:true;否則返回:false</returns> 43 ///</summary> 44 public bool CheckRequestForm() 45 { 46 if (request.Form.Count > 0) 47 { 48 foreach (string sqlParam in this.request.Form) 49 { 50 if (sqlParam == "__VIEWSTATE") 51 continue; 52 if (sqlParam == "__EVENTVALIDATION") 53 continue; 54 if (CheckKeyWord(request.Form[sqlParam])) 55 { 56 return true; 57 } 58 } 59 } 60 return false; 61 } 62 ///<summary> 63 ///檢查字串中是否包含Sql注入關鍵字 64 /// <param name="_key">被檢查的字串</param> 65 /// <returns>如果包含sql注入關鍵字,返回:true;否則返回:false</returns> 66 ///</summary> 67 private static bool CheckKeyWord(string _key) 68 { 69 string[] pattenKeyWord = StrKeyWord.Split('|'); 70 string[] pattenSymbol = StrSymbol.Split('|'); 71 foreach (string sqlParam in pattenKeyWord) 72 { 73 if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam)) 74 { 75 return true; 76 } 77 } 78 foreach (string sqlParam in pattenSymbol) 79 { 80 if (_key.Contains(sqlParam)) 81 { 82 return true; 83 } 84 } 85 return false; 86 } 87 88 }
SqlInjectHelper類中,對request的query引數和form引數進行的檢測,沒有對cookie的檢測,如有需要,可自行加上;
2、SqlInjectHelper在哪呼叫呢?
1)、如果想對整個web站點的所有請求都做sql關鍵字檢測,那就在Global.asax 的 Application_BeginRequest方法中呼叫;
1 protected void Application_BeginRequest(object sender, EventArgs e) 2 { 3 SqlInjectHelper myCheck = new SqlInjectHelper(Request); 4 bool result = myCheck.CheckSqlInject(); 5 if (result) 6 { 7 Response.ContentType = "text/plain"; 8 Response.Write("您提交的資料有惡意字元!"); 9 Response.End(); 10 } 11 }
2)、如果只需對某個介面檔案的介面進行sql關鍵字檢測,那隻需在該檔案開始處呼叫SqlInjectHelper類即可;
1 public class Handler1 : IHttpHandler 2 { 3 public void ProcessRequest(HttpContext context) 4 { 5 SqlInjectHelper myCheck = new SqlInjectHelper(context.Request); 6 bool result = myCheck.CheckSqlInject(); 7 context.Response.ContentType = "text/plain"; 8 context.Response.Write(result?"您提交的資料有惡意字元!":""); 9 context.Response.StatusCode = result ? 500 : 200; 10 } 11 public bool IsReusable 12 { 13 get 14 { 15 return false; 16 } 17 } 18 }
上面的程式碼就是對某個一般處理程式(ashx)添加了sql關鍵字檢測;
3、補充說明:asp.net中的 __VIEWSTATE、__EVENTVALIDATION、
在sql關鍵字檢測方法中,排除了__VIEWSTATE、__EVENTVALIDATION這兩個引數;
1)、__VIEWSTATE
ViewState是ASP.NET中用來儲存WEB控制元件回傳時狀態值一種機制。在WEB窗體(FORM)的設定為runat="server",這個窗體(FORM)會被附加一個隱藏的屬性_VIEWSTATE。_VIEWSTATE中存放了所有控制元件在ViewState中的狀態值。
ViewState是類Control中的一個域,其他所有控制元件通過繼承Control來獲得了ViewState功能。它的型別是system.Web.UI.StateBag,一個名稱/值的物件集合。
當請求某個頁面時,ASP.NET把所有控制元件的狀態序列化成一個字串,然後做為窗體的隱藏屬性送到客戶端。當客戶端把頁面回傳時,ASP.NET分析回傳的窗體屬性,並賦給控制元件對應的值;
2)、__EVENTVALIDATION
__EVENTVALIDATION只是用來驗證事件是否從合法的頁面傳送,只是一個數字簽名,所以一般很短。
“id”屬性為“__EVENTVALIDATION”的隱藏欄位是ASP.NET 2.0的新增的安全措施。該功能可以阻止由潛在的惡意使用者從瀏覽器端傳送的未經授權的請求.;
4、sql關鍵詞檢測的另一個版本:該版本將所有危險字元都放在了一個正則表示式中;
該類不僅檢測了sql常用關鍵字還有xss攻擊的常用關鍵字
1 public class SafeHelper 2 { 3 private const string StrRegex = @"<[^>]+?style=[\w]+?:expression\(|\b(alert|confirm|prompt)\b|^\+/v(8|9)|<[^>]*?=[^>]*?&#[^>]*?>|\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|<\s*img\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)"; 4 public static bool PostData() 5 { 6 bool result = false; 7 for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++) 8 { 9 result = CheckData(HttpContext.Current.Request.Form[i].ToString()); 10 if (result) 11 { 12 break; 13 } 14 } 15 return result; 16 } 17 18 public static bool GetData() 19 { 20 bool result = false; 21 for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++) 22 { 23 result = CheckData(HttpContext.Current.Request.QueryString[i].ToString()); 24 if (result) 25 { 26 break; 27 } 28 } 29 return result; 30 } 31 public static bool CookieData() 32 { 33 bool result = false; 34 for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++) 35 { 36 result = CheckData(HttpContext.Current.Request.Cookies[i].Value.ToLower()); 37 if (result) 38 { 39 break; 40 } 41 } 42 return result; 43 44 } 45 public static bool referer() 46 { 47 bool result = false; 48 return result = CheckData(HttpContext.Current.Request.UrlReferrer.ToString()); 49 } 50 public static bool CheckData(string inputData) 51 { 52 if (Regex.IsMatch(inputData, StrRegex)) 53 { 54 return true; 55 } 56 else 57 { 58 return false; 59 } 60 } 61 }
———————————————————————————————————&md