asp.net利用HttpModule实现防sql注入

  1、新建一个类,实现IHttpModule接口

  代码

  

复制代码 代码如下:

  public class SqlHttpModule : IHttpModule

  {

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  context.AcquireRequestState += new EventHandler(context_AcquireRequestState);

  }

  }

  在实现接口的Init方法时,我们选择了AcquireRequestState事件,为什么不是Begin_Request事件呢?这是因为我们在处理的时候可能用的session,而Begin_Request事件执行的时候还没有加载session状态(关于HttpModule可以参考这一篇)。

  2、对网站提交的数据进行处理

  (1)、GET方式

  代码

  

复制代码 代码如下:

  //url提交数据 get方式

  if (context.Request.QueryString != null)

  {

  for (int i = 0; i < context.Request.QueryString.Count; i++)

  {

  key = context.Request.QueryString.Keys[i];

  value = context.Server.UrlDecode(context.Request.QueryString[key]);

  if (!FilterSql(value))

  {

  throw new Exception("QueryString(GET) including dangerous sql key word!");

  }

  }

  }

  (2)、POST方式

  代码

  

复制代码 代码如下:

  //表单提交数据 post方式

  if (context.Request.Form != null)

  {

  for (int i = 0; i < context.Request.Form.Count; i++)

  {

  key = context.Request.Form.Keys[i];

  if (key == "__VIEWSTATE") continue;

  value = context.Server.HtmlDecode(context.Request.Form[i]);

  if (!FilterSql(value))

  {

  throw new Exception("Request.Form(POST) including dangerous sql key word!");

  }

  }

  }

  完整代码:

  代码

  

复制代码 代码如下:

  using System;

  using System.Collections.Generic;

  using System.Linq;

  using System.Web;

  using System.Web.UI;

  using System.Web.UI.WebControls;

  using System.Text;

  namespace DotNet.Common.WebForm

  {

  /// <summary>

  /// 简单防止sql注入

  /// </summary>

  public class SqlHttpModule : IHttpModule

  {

  public void Dispose()

  {

  }

  public void Init(HttpApplication context)

  {

  context.AcquireRequestState += new EventHandler(context_AcquireRequestState);

  }

  /// <summary>

  /// 处理sql注入

  /// </summary>

  /// <param name="sender"></param>

  /// <param name="e"></param>

  private void context_AcquireRequestState(object sender, EventArgs e)

  {

  HttpContext context = ((HttpApplication)sender).Context;

  try

  {

  string key = string.Empty;

  string value = string.Empty;

  //url提交数据 get方式

  if (context.Request.QueryString != null)

  {

  for (int i = 0; i < context.Request.QueryString.Count; i++)

  {

  key = context.Request.QueryString.Keys[i];

  value = context.Server.UrlDecode(context.Request.QueryString[key]);

  if (!FilterSql(value))

  {

  throw new Exception("QueryString(GET) including dangerous sql key word!");

  }

  }

  }

  //表单提交数据 post方式

  if (context.Request.Form != null)

  {

  for (int i = 0; i < context.Request.Form.Count; i++)

  {

  key = context.Request.Form.Keys[i];

  if (key == "__VIEWSTATE") continue;

  value = context.Server.HtmlDecode(context.Request.Form[i]);

  if (!FilterSql(value))

  {

  throw new Exception("Request.Form(POST) including dangerous sql key word!");

  }

  }

  }

  }

  catch (Exception ex)

  {

  throw ex;

  }

  }

  /// <summary>

  /// 过滤非法关键字,这个可以按照项目灵活配置

  /// </summary>

  /// <param name="key"></param>

  /// <returns></returns>

  private bool FilterSql(string key)

  {

  bool flag = true;

  try

  {

  if (!string.IsNullOrEmpty(key))

  {

  //一般配置在公共的文件中,如xml文件,txt文本等等

  string sqlStr = "insert |delete |select |update |exec |varchar |drop |creat |declare |truncate |cursor |begin |open|<-- |--> ";

  string[] sqlStrArr = sqlStr.Split('|');

  foreach (string strChild in sqlStrArr)

  {

  if (key.ToUpper().IndexOf(strChild.ToUpper()) != -1)

  {

  flag = false;

  break;

  }

  }

  }

  }

  catch

  {

  flag = false;

  }

  return flag;

  }

  }

  }

  3、在web项目中应用

  只要在web.config的httpModules节点下面添加如下配置即可。

  <httpModules>

  <add name="SqlHttpModule" type="DotNet.Common.WebForm.SqlHttpModule, DotNet.Common.WebForm"></add>

  </httpModules>

  需要说明的是,这个防止sql注入的方法在特定的小项目中还是很简洁高效的,但是不通用,通常我们都是选择参数化(利用orm或者ado.net的参数化)方式防止sql注入。

  附:asp.net在网页头部引入js脚本的简单方法

  asp.net开发少不了JavaScript的辅助。在通常项目中,js文件都组织在一个公共目录如js文件夹下。随着项目的深入,你会发现js脚本文件越来越多,公共的脚步库越来越庞大。实际使用的时候,我们通常都是在页面中通过 <script src="..." type="text/javascript" >形式引入js文件,而且引入的越来越多。下面我们就来简单讨论在每个页面引入公共脚本库的统一方式,而不用每个页面都是很多<script src="..." type="text/javascript" >的形式。

  和我们以前的做法一样,定义一个页面基类叫BasePage,事件和方法如下:

  Code

  

复制代码 代码如下:

  using System;

  using System.Data;

  using System.Configuration;

  using System.Collections.Generic;

  using System.Web;

  using System.Web.Security;

  using System.Web.UI;

  using System.Web.UI.WebControls;

  using System.Web.UI.WebControls.WebParts;

  using System.Web.UI.HtmlControls;

  using System.Reflection;

  using System.Text;

  using System.IO;

  namespace DotNet.Common.WebForm

  {

  using DotNet.Common.Model;

  using DotNet.Common.Util;

  public class BasePage : System.Web.UI.Page

  {

  public BasePage()

  {

  }

  protected override void OnInit(EventArgs e)

  {

  base.OnInit(e);

  AddHeaderJs();//向网页头部添加js等文件

  }

  #region 网页头添加通用统一js文件

  private void AddHeaderJs()

  {

  string jsPath = "~/js/";

  string filePath = Server.MapPath(jsPath);

  Literal lit = new Literal();

  StringBuilder sb = new StringBuilder();

  if (!Directory.Exists(filePath))

  throw new Exception("路径不存在");

  List<string> listJs = new List<string>();

  foreach (var item in Directory.GetFiles(filePath, "*.js", SearchOption.TopDirectoryOnly))

  {

  listJs.Add(Path.GetFileName(item));

  }

  foreach (var jsname in listJs)

  {

  sb.Append(ScriptInclude(jsPath + jsname));

  }

  lit.Text = sb.ToString();

  Header.Controls.AddAt(1, lit);

  }

  private string ResolveHeaderUrl(string relativeUrl)

  {

  string url = null;

  if (string.IsNullOrEmpty(relativeUrl))

  {

  url = string.Empty;

  }

  else if (!relativeUrl.StartsWith("~"))

  {

  url = relativeUrl;

  }

  else

  {

  var basePath = HttpContext.Current.Request.ApplicationPath;

  url = basePath + relativeUrl.Substring(1);

  url = url.Replace("//", "/");

  }

  return url;

  }

  private string ScriptInclude(string url)

  {

  if (string.IsNullOrEmpty(url))

  throw new Exception("路径不存在");

  string path = ResolveHeaderUrl(url);

  return string.Format(@"<script src='{0}' type='text/javascript'></script>", path);

  }

  #endregion

  }

  }

  这样就简单地解决了引入公共js的问题。同样的原理,你也可以引入其他类型的文件,如css等。

  demo下载