也谈C#.NET防止SQL注入式攻击
出处:http://www.cnblogs.com/jacky73/archive/2009/09/02/1558770.html
#region 防止sql注入式攻击(可用于UI层控制)
/// /// 判断字符串中是否有SQL攻击代码,by fangbo.yu 2008.07.18 /// /// 传入用户提交数据 /// true-安全;false-有注入攻击现有; public bool ProcessSqlStr(string inputString) { string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators"; try { if ((inputString != null) && (inputString != String.Empty)) { string str_Regex = @"\b(" + SqlStr + @")\b";
Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase); //string s = Regex.Match(inputString).Value; if (true == Regex.IsMatch(inputString)) return false;
} } catch { return false ; } return true; }
/// /// 处理用户提交的请求,校验sql注入式攻击,在页面装置时候运行 /// System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); 为用户自定义错误页面提示地址, /// 在Web.Config文件时里面添加一个 ErrorPage 即可 /// /// /// public void ProcessRequest() { try { string getkeys = ""; string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); if (System.Web.HttpContext.Current.Request.QueryString != null) {
for (int i = 0; i < System.Web.HttpContext.Current.Request.QueryString.Count; i++) { getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i]; if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys])) { System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!"); System.Web.HttpContext.Current.Response.End(); } } } if (System.Web.HttpContext.Current.Request.Form != null) { for (int i = 0; i < System.Web.HttpContext.Current.Request.Form.Count; i++) { getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i]; if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys])) { System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!"); System.Web.HttpContext.Current.Response.End(); } } } } catch { // 错误处理: 处理用户提交信息! } } #endregion
#region 转换sql代码(也防止sql注入式攻击,可以用于业务逻辑层,但要求UI层输入数据时候进行解码) /// /// 提取字符固定长度,by fangbo.yu 2008.07.18 /// /// /// /// public string CheckStringLength(string inputString, Int32 maxLength) { if ((inputString != null) && (inputString != String.Empty)) { inputString = inputString.Trim();
if (inputString.Length > maxLength) inputString = inputString.Substring(0, maxLength); } return inputString; }
/// /// 将输入字符串中的sql敏感字,替换成"[敏感字]",要求输出时,替换回来,by fangbo.yu 2008.07.21 /// /// /// public string MyEncodeInputString(string inputString) { //要替换的敏感字 string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators"; try { if ((inputString != null) && (inputString != String.Empty)) { string str_Regex = @"\b(" + SqlStr + @")\b"; Regex Regex = new Regex(str_Regex,RegexOptions.IgnoreCase); //string s = Regex.Match(inputString).Value; MatchCollection matches = Regex.Matches(inputString); for (int i = 0; i < matches.Count; i++) inputString = inputString.Replace(matches[i].Value, "[" + matches[i].Value + "]"); } } catch { return ""; } return inputString;
}
/// /// 将已经替换成的"[敏感字]",转换回来为"敏感字",by fangbo.yu 2008.07.21 /// /// /// public string MyDecodeOutputString(string outputstring) { //要替换的敏感字 string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators"; try { if ((outputstring != null) && (outputstring != String.Empty)) { string str_Regex = @"\[\b(" + SqlStr + @")\b\]"; Regex Regex = new Regex(str_Regex,RegexOptions.IgnoreCase); MatchCollection matches = Regex.Matches(outputstring); for (int i = 0; i < matches.Count; i++) outputstring = outputstring.Replace(matches[i].Value, matches[i].Value.Substring(1, matches[i].Value.Length - 2)); } } catch { return ""; } return outputstring; } #endregion
我们的解决方式是:
1、首先在UI录入时,要控制数据的类型和长度、防止SQL注入式攻击,系统提供检测注入式攻击的函数,一旦检测出注入式攻击,该数据即不能提交; 2、业务逻辑层控制,通过在方法内部将SQL关键字用一定的方法屏蔽掉,然后检查数据长度,保证提交SQL时,不会有SQL数据库注入式攻击代码;但是这样处理后,要求UI输出时将屏蔽的字符还原。因此系统提供屏蔽字符 的函数和还原字符的函数。 3、在数据访问层,绝大多数采用存储过程访问数据,调用时以存储过程参数的方式访问,也会很好的防止注入式攻击。
浙公网安备 33010602011771号