#防 sql 注入的常用方法:
1, 服务端对前端传过来的参数值进行类型验证;
2, 服务端执行 sql, 使用参数化传值, 而不要使用 sql 字符串拼接;
3, 服务端对前端传过来的数据进行 sql 关键词过来与检测;
# 着重记录下服务端进行 sql 关键词检测:
1,sql 关键词检测类:
- public class SqlInjectHelper:System.web.UI.Page
- {
- 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";
- private static string StrSymbol = ";|(|)|[|]|{|}|%|@|*|'|!";
- private HttpRequest request;
- public SqlInjectHelper(System.Web.HttpRequest _request)
- {
- this.request = _request;
- }
- public bool CheckSqlInject()
- {
- return CheckRequestQuery() || CheckRequestForm();
- }
- ///<summary>
- /// 检查 URL 中是否包含 Sql 注入
- /// <param name="_request">当前 HttpRequest 对象</param>
- /// <returns > 如果包含 sql 注入关键字, 返回: true; 否则返回: false</returns>
- ///</summary>
- public bool CheckRequestQuery()
- {
- if (request.QueryString.Count> 0)
- {
- foreach (string sqlParam in this.request.QueryString)
- {
- if (sqlParam == "__VIEWSTATE")
- continue;
- if (sqlParam == "__EVENTVALIDATION")
- continue;
- if (CheckKeyWord(request.QueryString[sqlParam].ToLower()))
- {
- return true;
- }
- }
- }
- return false;
- }
- ///<summary>
- /// 检查提交的表单中是否包含 Sql 注入关键字
- /// <param name="_request">当前 HttpRequest 对象</param>
- /// <returns > 如果包含 sql 注入关键字, 返回: true; 否则返回: false</returns>
- ///</summary>
- public bool CheckRequestForm()
- {
- if (request.Form.Count> 0)
- {
- foreach (string sqlParam in this.request.Form)
- {
- if (sqlParam == "__VIEWSTATE")
- continue;
- if (sqlParam == "__EVENTVALIDATION")
- continue;
- if (CheckKeyWord(request.Form[sqlParam]))
- {
- return true;
- }
- }
- }
- return false;
- }
- ///<summary>
- /// 检查字符串中是否包含 Sql 注入关键字
- /// <param name="_key">被检查的字符串</param>
- /// <returns > 如果包含 sql 注入关键字, 返回: true; 否则返回: false</returns>
- ///</summary>
- private static bool CheckKeyWord(string _key)
- {
- string[] pattenKeyWord = StrKeyWord.Split('|');
- string[] pattenSymbol = StrSymbol.Split('|');
- foreach (string sqlParam in pattenKeyWord)
- {
- if (_key.Contains(sqlParam + "") || _key.Contains(" " + sqlParam))
- {
- return true;
- }
- }
- foreach (string sqlParam in pattenSymbol)
- {
- if (_key.Contains(sqlParam))
- {
- return true;
- }
- }
- return false;
- }
- }
SqlInjectHelper 类中, 对 request 的 query 参数和 form 参数进行的检测, 没有对 cookie 的检测, 如有需要, 可自行加上;
2,SqlInjectHelper 在哪调用呢?
1), 如果想对整个 Web 站点的所有请求都做 sql 关键字检测, 那就在 Global.asax 的 Application_BeginRequest 方法中调用;
- protected void Application_BeginRequest(object sender, EventArgs e)
- {
- SqlInjectHelper myCheck = new SqlInjectHelper(Request);
- bool result = myCheck.CheckSqlInject();
- if (result)
- {
- Response.ContentType = "text/plain";
- Response.Write("您提交的数据有恶意字符!");
- Response.End();
- }
- }
2), 如果只需对某个接口文件的接口进行 sql 关键字检测, 那只需在该文件开始处调用 SqlInjectHelper 类即可;
- public class Handler1 : IHttpHandler
- {
- public void ProcessRequest(HttpContext context)
- {
- SqlInjectHelper myCheck = new SqlInjectHelper(context.Request);
- bool result = myCheck.CheckSqlInject();
- context.Response.ContentType = "text/plain";
- context.Response.Write(result?"您提交的数据有恶意字符!":"");
- context.Response.StatusCode = result ? 500 : 200;
- }
- public bool IsReusable
- {
- get
- {
- return false;
- }
- }
- }
上面的代码就是对某个一般处理程序 (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 攻击的常用关键字
- public class SafeHelper
- {
- 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)";
- public static bool PostData()
- {
- bool result = false;
- for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)
- {
- result = CheckData(HttpContext.Current.Request.Form[i].ToString());
- if (result)
- {
- break;
- }
- }
- return result;
- }
- public static bool GetData()
- {
- bool result = false;
- for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
- {
- result = CheckData(HttpContext.Current.Request.QueryString[i].ToString());
- if (result)
- {
- break;
- }
- }
- return result;
- }
- public static bool CookieData()
- {
- bool result = false;
- for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++)
- {
- result = CheckData(HttpContext.Current.Request.Cookies[i].Value.ToLower());
- if (result)
- {
- break;
- }
- }
- return result;
- }
- public static bool referer()
- {
- bool result = false;
- return result = CheckData(HttpContext.Current.Request.UrlReferrer.ToString());
- }
- public static bool CheckData(string inputData)
- {
- if (Regex.IsMatch(inputData, StrRegex))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- ------------------------------------
来源: https://www.cnblogs.com/willingtolove/p/11069969.html