人民医院API

SqlChecker.cs 7.4KB

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