分析是一门科学,设计是一门艺术

每天进步一点点

导航

使用 HttpModule实现sql防注入

 sql注入是被谈的很多的一个话题,有很多的方法能够实现sql的防注入,在这里就简单说一下如果使用HttpModule来实现sql的防注入。

    在项目中添加一个类让其实现IHttpModule接口。IHttpModule接口有两个方法 Init 和 Dispose。然后在Init方法中来订阅

 AcquireRequestState事件。

  1.     public void Dispose()
  2.     {
  3.         
  4.     }
  5.     public void Init(HttpApplication context)
  6.     {
  7.         //Begin_Request时还没有加载Session状态
  8.         context.AcquireRequestState += new EventHandler(context_AcquireRequestState);
  9.     }

    为什么是AcquireRequestState 事件而不是Begin_Request呢 ,因为在Begin_Request执行的时候还没有加载session状态,而在处理的时侯可能会用到session。

    在AcquireRequestState 事件中我们就要进行相应的处理了,思路如下,一般网站提交数据只有两个地方,表单和url,所以就在该事件中将从这两处提交的数据截取,判断是否有一些危险字符,然后做相应处理。代码如下

  1. private void context_AcquireRequestState(object sender, EventArgs e)
  2.     {
  3.         HttpContext context = ((HttpApplication)sender).Context;
  4.         try
  5.         {
  6.             string getkeys = string.Empty;
  7.             string sqlErrorPage = "~/Error.aspx";//转向的错误提示页面 
  8.             string keyvalue = string.Empty;
  9.             string requestUrl = context.Request.Path.ToString();
  10.             //url提交数据
  11.             if (context.Request.QueryString != null)
  12.             {
  13.                 for (int i = 0; i < context.Request.QueryString.Count; i++)
  14.                 {
  15.                     getkeys = context.Request.QueryString.Keys[i];
  16.                     keyvalue = context.Server.UrlDecode(context.Request.QueryString[getkeys]);
  17.                     if (!ProcessSqlStr(keyvalue))
  18.                     {
  19.                         context.Response.Redirect(sqlErrorPage);
  20.                         context.Response.End();
  21.                         break;
  22.                     }
  23.                 }
  24.             }
  25.             //表单提交数据
  26.             if (context.Request.Form != null)
  27.             {
  28.                 for (int i = 0; i < context.Request.Form.Count; i++)
  29.                 {
  30.                     getkeys = context.Request.Form.Keys[i];
  31.                     keyvalue = context.Server.HtmlDecode(context.Request.Form[i]);//[getkeys];
  32.                     if (getkeys == "__VIEWSTATE"continue;
  33.                     if (!ProcessSqlStr(keyvalue))
  34.                     {
  35.                         context.Response.Redirect(sqlErrorPage);
  36.                         context.Response.End();
  37.                         break;
  38.                     }
  39.                 }
  40.             }
  41.         }
  42.         catch (Exception ex)
  43.         {
  44.         }
  45.     }

    上面的代码只是做了简单的处理,当然也可以在事件中将输入非法关键字的用户ip ,操作页面的url,时间等信息记录在数据库中或是记录在日志中。

而且还用到了一个叫ProcessSqlStr的方法,这个方法就是用来处理字符串的,判断是否合法,如下

  1.  private bool ProcessSqlStr(string str)
  2.     {
  3.         bool returnValue = true;
  4.         try
  5.         {
  6.             if (str.Trim() != "")
  7.             {
  8.                 //string sqlStr = ConfigurationManager.AppSettings["FilterSql"].Trim();
  9.                 string sqlStr = "declare |exec|varchar|cursor|begin|open |drop |creat |select |truncate";
  10.                 string[] sqlStrs = sqlStr.Split('|');
  11.                 foreach (string ss in sqlStrs)
  12.                 {
  13.                     if (str.ToLower().IndexOf(ss) >= 0)
  14.                     {
  15.                         m_sqlstr = ss;
  16.                         returnValue = false;
  17.                         break;
  18.                     }
  19.                 }
  20.             }
  21.         }
  22.         catch
  23.         {
  24.             returnValue = false;
  25.         }
  26.         return returnValue;
  27.     }

    到这儿类就写好了,再在web.config中做相应的配置就大功告成

  1.   <httpModules>
  2.       <add type="HttpModule" name="HttpModule"/>
  3.   </httpModules>

   用这种方法很方便,只需在这一处做处理,全站都能应用到,不过如果一个用户想用varchar 等sql的关键字来做用户名注册的话也会被挡掉,不过应该没有人这么无聊吧,呵呵

posted on 2008-11-24 14:37  布衣(Dream2008)  阅读(260)  评论(0编辑  收藏  举报