http://s.sams.cnblogs.com/articles/377924.html
昨天刚把数据库防注入的原型发了上去,发觉好像还漏了点东西,现在把它全部补上.
Sql注入是常常被一些菜鸟级黑客高手惯用的手法, 就是基于Sql的注入实现, 防注入程序其实就是处理Http请求,把Get和Post的请求数据中做过滤.

通过相应的关键字去识别是否有 Sql注入攻击代码
 string SqlStr = "and |exec |insert |select |delete |update |count | * |chr |mid |master |truncate |char |declare ";
在下面的代码中你要看以上面的定义, 其实就是定义要识别的关键字.

而我们处理请求一般都是通过 Request.QueryString / Request.Form 这两种, 我们可以专门写一个类去处理这些请求, 但如果在每一个处理环节都载入这个类去做处理, 那太麻烦了. 

如果写一个ISAPI当然也能完成这个功能的实现, 但在.NET 中 HttpModule帮我们实现了类似于ISAPI Filter的功能, 所以改为通过 HttpModule 去处理这些事情是最好不过的啦.

我们现在要用到的只是里面的BeginRequest这个事件, 所以只需要注册BeginRequest这个事件就可以了.

 1 public class SqlstrAny : IHttpModule 
 2 {
 3  public void Init(HttpApplication application) 
 4  
 5   application.BeginRequest += (new 
 6    EventHandler(this.Application_BeginRequest));
 7  }

 8  private void Application_BeginRequest(Object source, EventArgs e) 
 9  {
10   ProcessRequest pr = new ProcessRequest();
11   pr.StartProcessRequest();
12  }
      
13  public void Dispose() 
14  {
15  }

16 }

17 public class ProcessRequest
18 {
19  (数据库防注入的核心 请参阅: http://s.sams.cnblogs.com/articles/377624.html)
20 }

记得在前面载入相应名字空间哦.
 using System;
 using System.Web;

忘了还得加个自定名字空间 namespace Theme.Script

以上就是通Application_BeginRequest实现的
 ProcessRequest pr = new ProcessRequest();
 pr.StartProcessRequest();
 (数据库防注入的核心 请参阅: http://s.sams.cnblogs.com/articles/377624.html)

完整的类如下:

//-----------------SqlstrAny.cs------------------------

  1using System;
  2using System.Web; 
  3namespace Theme.Script
  4{
  5 public class SqlstrAny : IHttpModule 
  6 {
  7  public void Init(HttpApplication application) 
  8  
  9   application.BeginRequest += (new 
 10    EventHandler(this.Application_BeginRequest));
 11  }

 12  private void Application_BeginRequest(Object source, EventArgs e) 
 13  {
 14   //HttpApplication Application = (HttpApplication)source;
 15   //HttpResponse Response=Application.Context.Response;
 16   //Response.Write("<h1>Beginning of Request</h1><hr>");
 17   ProcessRequest pr = new ProcessRequest();
 18   pr.StartProcessRequest();
 19  }
      
 20  public void Dispose() 
 21  {
 22  }

 23 }

 24
 25 public class ProcessRequest
 26 {
 27  #region SQL注入式攻击代码分析
 28  /// <summary>
 29  /// 处理用户提交的请求
 30  /// </summary>

 31  public void StartProcessRequest()
 32  {
 33   try
 34   {
 35    string getkeys = "";
 36    string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["CustomErrorPage"].ToString();
 37    if (System.Web.HttpContext.Current.Request.QueryString != null)
 38    {
 39    
 40     for(int i=0;i<System.Web.HttpContext.Current.Request.QueryString.Count;i++)
 41     {
 42      getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i];
 43      if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys]))
 44      {
 45       System.Web.HttpContext.Current.Response.Redirect (sqlErrorPage+"?errmsg=sqlserver&sqlprocess=true");
 46       System.Web.HttpContext.Current.Response.End();
 47      }

 48     }

 49    }

 50    if (System.Web.HttpContext.Current.Request.Form != null)
 51    {
 52     for(int i=0;i<System.Web.HttpContext.Current.Request.Form.Count;i++)
 53     {
 54      getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i];
 55      if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys]))
 56      {
 57       System.Web.HttpContext.Current.Response.Redirect (sqlErrorPage+"?errmsg=sqlserver&sqlprocess=true");
 58       System.Web.HttpContext.Current.Response.End();
 59      }

 60     }

 61    }

 62   }

 63   catch
 64   {
 65    // 错误处理: 处理用户提交信息!
 66   }

 67  }

 68  /// <summary>
 69  /// 分析用户请求是否正常
 70  /// </summary>
 71  /// <param name="Str">传入用户提交数据</param>
 72  /// <returns>返回是否含有SQL注入式攻击代码</returns>

 73  private bool ProcessSqlStr(string Str)
 74  {
 75   bool ReturnValue = true;
 76   try
 77   {
 78    if (Str != "")
 79    {
 80     string SqlStr = "and |exec |insert |select |delete |update |count | * |chr |mid |master |truncate |char |declare ";
 81     string[] anySqlStr = SqlStr.Split('|');
 82     foreach (string ss in anySqlStr)
 83     {
 84      if (Str.IndexOf(ss)>=0)
 85      {
 86       ReturnValue = false;
 87      }

 88     }

 89    }

 90   }

 91   catch
 92   {
 93    ReturnValue = false;
 94   }

 95   return ReturnValue;
 96  }

 97  #endregion

 98 }

 99
100}

101
102


编写完处理后,我们把它生成类库请在Bin的目录下

csc.exe /t:library SqlstrAny.cs /r:C:\windows\Microsoft.NET\Framework\v1.1.4322\Microsoft.VisualBasic.dll 

编译完后你会发现已经生成了一个 SqlstrAny.Dll 文件,这个就是我们需要的.

最后在 Web.Config 中注册它就可以用了.

 <system.web>
  
<httpModules>
   
<add name="SqlstrAny" type="Theme.Script.SqlstrAny,SqlstrAny" />
  
</httpModules>
 
</system.web>

最后别忘了在 Web.Config 中加入错误处理的导向页面哦.

 <add key="CustomErrorPage" value="../Error.html" />

至此,所有步骤就完成了, 打你的项目运行它, 在URL后加上 Select / and ...试试

http://localhost/Theme.Script/Process/CreatePay.aspx?action=select s&t=true

OK,完成!

源码下载: https://files.cnblogs.com/S.Sams/SqlstrAny.rar

这只是一个思路,完成可以可以再把字符做一下编码处理同样也可以达到你的目的.
如: and = and 即 and在网页显示的是and
select = select

实际就是做16进制编码, 这样实现起来会更科学. 可以保持原有的内容一致的情况下实现防SQL注入!