防止sql注入式攻击 SQL注入学习——三层架构
解决方案是:
1、首先在UI录入时,要控制数据的类型和长度、防止SQL注入式攻击,系统提供检测注入式攻击的函数,一旦检测出注入式攻击,该数据即不能提交;
2、业务逻辑层控制,通过在方法内部将SQL关键字用一定的方法屏蔽掉,然后检查数据长度,保证提交SQL时,不会有SQL数据库注入式攻击代码;但是这样处理后,要求UI输出时将屏蔽的字符还原。因此系统提供屏蔽字符 的函数和还原字符的函数。
3、在数据访问层,绝大多数采用存储过程访问数据,调用时以存储过程参数的方式访问,也会很好的防止注入式攻击。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/**//// /// 判断字符串中是否有SQL攻击代码 /// /// 传入用户提交数据 /// 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; }
32 /**//// 33 /// 处理用户提交的请求,校验sql注入式攻击,在页面装置时候运行 34 /// System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); 为用户自定义错误页面提示地址, 35 /// 在Web.Config文件时里面添加一个 ErrorPage 即可 36 /// 37 /// 38 /// 39 public void ProcessRequest() 40 { 41 try 42 { 43 string getkeys = ""; 44 string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); 45 if (System.Web.HttpContext.Current.Request.QueryString != null) 46 { 47 48 for (int i = 0; i < System.Web.HttpContext.Current.Request.QueryString.Count; i++) 49 { 50 getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i]; 51 if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys])) 52 { 53 System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!"); 54 System.Web.HttpContext.Current.Response.End(); 55 } 56 } 57 } 58 if (System.Web.HttpContext.Current.Request.Form != null) 59 { 60 for (int i = 0; i < System.Web.HttpContext.Current.Request.Form.Count; i++) 61 { 62 getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i]; 63 if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys])) 64 { 65 System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!"); 66 System.Web.HttpContext.Current.Response.End(); 67 } 68 } 69 } 70 } 71 catch 72 { 73 // 错误处理: 处理用户提交信息! 74 } 75 } 76 #endregion 77 78 79 80
81 //转换sql代码(也防止sql注入式攻击,可以用于业务逻辑层,但要求UI层输入数据时候进行解码)#region // 转换sql代码(也防止sql注入式攻击,可以用于业务逻辑层,但要求UI层输入数据时候进行解码) 82 /**//// 83 /// 提取字符固定长度 84 /// 85 /// 86 /// 87 /// 88 public string CheckStringLength(string inputString, Int32 maxLength) 89 { 90 if ((inputString != null) && (inputString != String.Empty)) 91 { 92 inputString = inputString.Trim(); 93 94 if (inputString.Length > maxLength) 95 inputString = inputString.Substring(0, maxLength); 96 } 97 return inputString; 98 } 99
100 /**//// 101 /// 将输入字符串中的sql敏感字,替换成"[敏感字]",要求输出时,替换回来 102 /// 103 /// 104 /// 105 public string MyEncodeInputString(string inputString) 106 { 107 //要替换的敏感字 108 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"; 109 try 110 { 111 if ((inputString != null) && (inputString != String.Empty)) 112 { 113 string str_Regex = @"\b(" + SqlStr + @")\b"; 114 115 Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase); 116 //string s = Regex.Match(inputString).Value; 117 MatchCollection matches = Regex.Matches(inputString); 118 for (int i = 0; i < matches.Count; i++) 119 inputString = inputString.Replace(matches[i].Value, "[" + matches[i].Value + "]"); 120 121 } 122 } 123 catch 124 { 125 return ""; 126 } 127 return inputString; 128 129 } 130
131 /**//// 132 /// 将已经替换成的"[敏感字]",转换回来为"敏感字" 133 /// 134 /// 135 /// 136 public string MyDecodeOutputString(string outputstring) 137 { 138 //要替换的敏感字 139 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"; 140 try 141 { 142 if ((outputstring != null) && (outputstring != String.Empty)) 143 { 144 string str_Regex = @"\[\b(" + SqlStr + @")\b\]"; 145 Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase); 146 MatchCollection matches = Regex.Matches(outputstring); 147 for (int i = 0; i < matches.Count; i++) 148 outputstring = outputstring.Replace(matches[i].Value, matches[i].Value.Substring(1, matches[i].Value.Length - 2)); 149 150 } 151 } 152 catch 153 { 154 return ""; 155 } 156 return outputstring; 157 } 158 #endregion