Bez popisu

SqlChecker.cs 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Web;
  7. namespace CallCenter.Utility
  8. {
  9. public class SqlChecker
  10. { //当前请求对象
  11. private HttpRequest request;
  12. //当前响应对象
  13. private HttpResponse response;
  14. //安全Url,当出现Sql注入时,将导向到的安全页面,如果没赋值,则停留在当前页面
  15. private string safeUrl = String.Empty;
  16. //Sql注入时,可能出现的sql关键字,可根据自己的实际情况进行初始化,每个关键字由'|'分隔开来
  17. //private const string StrKeyWord = @"select|insert|delete|from|count(|drop table|update|truncate|asc(|mid(|char(|xp_cmdshell|exec master|netlocalgroup administrators|:|net user|""|or|and";
  18. private const string StrKeyWord = @"select|insert|delete|from|drop table|update|truncate|exec master|netlocalgroup administrators|net user|or|and|waitfor delay|waitfor|delay";
  19. //Sql注入时,可能出现的特殊符号,,可根据自己的实际情况进行初始化,每个符号由'|'分隔开来
  20. // private const string StrRegex = @"@|*";
  21. //private const string StrRegex = @"=|!|'";
  22. public SqlChecker()
  23. {
  24. //
  25. // TODO: 在此处添加构造函数逻辑
  26. //
  27. }
  28. /// <summary>
  29. /// 由此构造函数创建的对象,在验证Sql注入之后将停留在原来页面上
  30. /// </summary>
  31. /// <param name="_request">当前请求的 Request 对象</param>
  32. /// <param name="_response">当前请求的 Response 对象</param>
  33. public SqlChecker(HttpRequest _request, HttpResponse _response)
  34. {
  35. this.request = _request;
  36. this.response = _response;
  37. }
  38. /// <summary>
  39. /// 由此构造函数创建的对象,在验证Sql注入之后将请求将导向由 _safeUrl 指定的安全url页面上
  40. /// </summary>
  41. /// <param name="_request">当前请求的 Request 对象</param>
  42. /// <param name="_response">当前请求的 Response 对象</param>
  43. /// <param name="_safeUrl">验证Sql注入之后将导向的安全 url</param>
  44. public SqlChecker(HttpRequest _request, HttpResponse _response, string _safeUrl)
  45. {
  46. this.request = _request;
  47. this.response = _response;
  48. this.safeUrl = _safeUrl;
  49. }
  50. /// <summary>
  51. /// 只读属性 SQL关键字
  52. /// </summary>
  53. public string KeyWord
  54. {
  55. get
  56. {
  57. return StrKeyWord;
  58. }
  59. }
  60. ///// <summary>
  61. ///// 只读属性过滤特殊字符
  62. ///// </summary>
  63. //public string RegexString
  64. //{
  65. // get
  66. // {
  67. // return StrRegex;
  68. // }
  69. //}
  70. /// <summary>
  71. /// 当出现Sql注入时需要提示的错误信息(主要是运行一些客户端的脚本)
  72. /// </summary>
  73. public string Msg
  74. {
  75. get
  76. {
  77. string msg = "<script type='text/javascript'> "
  78. + " alert('请勿输入非法字符!'); ";
  79. if (this.safeUrl == String.Empty)
  80. msg += " window.location.href = '" + request.RawUrl + "'";
  81. else
  82. msg += " window.location.href = '" + safeUrl + "'";
  83. msg += "</script>";
  84. return msg;
  85. }
  86. }
  87. /// <summary>
  88. /// 检查URL参数中是否带有SQL注入的可能关键字。
  89. /// </summary>
  90. /// <returns>存在SQL注入关键字时返回 true,否则返回 false</returns>
  91. public bool CheckRequestQuery()
  92. {
  93. bool result = false;
  94. if (request.QueryString.Count != 0)
  95. {
  96. //若URL中参数存在,则逐个检验参数。
  97. foreach (string queryName in this.request.QueryString)
  98. {
  99. //过虑一些特殊的请求状态值,主要是一些有关页面视图状态的参数
  100. if (queryName == "__VIEWSTATE" || queryName == "__EVENTVALIDATION")
  101. continue;
  102. //开始检查请求参数值是否合法
  103. if (CheckKeyWord(request.QueryString[queryName]))
  104. {
  105. //只要存在一个可能出现Sql注入的参数,则直接退出
  106. result = true;
  107. break;
  108. }
  109. }
  110. }
  111. return result;
  112. }
  113. /// <summary>
  114. /// 检查提交表单中是否存在SQL注入的可能关键字
  115. /// </summary>
  116. /// <returns>存在SQL注入关键字时返回 true,否则返回 false</returns>
  117. public bool CheckRequestForm()
  118. {
  119. bool result = false;
  120. if (request.Form.Count > 0)
  121. {
  122. //若获取提交的表单项个数不为0,则逐个比较参数
  123. foreach (string queryName in this.request.Form)
  124. {
  125. //过虑一些特殊的请求状态值,主要是一些有关页面视图状态的参数
  126. if (queryName == "__VIEWSTATE" || queryName == "__EVENTVALIDATION")
  127. continue;
  128. //开始检查提交的表单参数值是否合法
  129. if (CheckKeyWord(request.Form[queryName]))
  130. {
  131. //只要存在一个可能出现Sql注入的参数,则直接退出
  132. result = true;
  133. break;
  134. }
  135. }
  136. }
  137. return result;
  138. }
  139. /// <summary>
  140. /// 检查_sword是否包涵SQL关键字
  141. /// </summary>
  142. /// <param name="_sWord">需要检查的字符串</param>
  143. /// <returns>存在SQL注入关键字时返回 true,否则返回 false</returns>
  144. public bool CheckKeyWord(string _sWord)
  145. {
  146. bool result = false;
  147. //模式1 : 对应Sql注入的可能关键字
  148. string[] patten1 = StrKeyWord.Split('|');
  149. //模式2 : 对应Sql注入的可能特殊符号
  150. // string[] patten2 = StrRegex.Split('|');
  151. //开始检查 模式1:Sql注入的可能关键字 的注入情况
  152. foreach (string sqlKey in patten1)
  153. {
  154. if (_sWord.IndexOf(" " + sqlKey) >= 0 || _sWord.IndexOf(sqlKey + " ") >= 0)
  155. {
  156. //只要存在一个可能出现Sql注入的参数,则直接退出
  157. result = true;
  158. break;
  159. }
  160. }
  161. //开始检查 模式1:Sql注入的可能特殊符号 的注入情况
  162. //foreach (string sqlKey in patten2)
  163. //{
  164. // if (_sWord.IndexOf(sqlKey) >= 0)
  165. // {
  166. // //只要存在一个可能出现Sql注入的参数,则直接退出
  167. // result = true;
  168. // break;
  169. // }
  170. //}
  171. return result;
  172. }
  173. /// <summary>
  174. /// 执行Sql注入验证
  175. /// </summary>
  176. public void Check()
  177. {
  178. if (CheckRequestQuery() || CheckRequestForm())
  179. {
  180. response.Write(Msg);
  181. response.End();
  182. }
  183. }
  184. }
  185. }