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

摘要:
Sql注入已经被许多人讨论过。这篇文章没有新特性,也不够普遍。nnd,我不想让你流口水。我只是觉得这很简单,想法很有参考价值。这是因为我们可能在处理时使用会话,而Begin_在执行请求事件时尚未加载会话状态。

关于sql注入,已经被很多人讨论过了。这篇没有新意功能也不够通用,nnd,不想引起口水,就是觉得简单而且思路有参考性才贴出来。
1、新建一个类,实现IHttpModule接口

asp.net简单实现利用HttpModule实现防sql注入第1张asp.net简单实现利用HttpModule实现防sql注入第2张代码
    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方式

asp.net简单实现利用HttpModule实现防sql注入第3张asp.net简单实现利用HttpModule实现防sql注入第4张代码
  //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方式

asp.net简单实现利用HttpModule实现防sql注入第5张asp.net简单实现利用HttpModule实现防sql注入第6张代码
        //表单提交数据 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!");
                        }
                    }
                }

 完整代码:

asp.net简单实现利用HttpModule实现防sql注入第7张asp.net简单实现利用HttpModule实现防sql注入第8张代码
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="http://t.zoukankan.com/..." type="text/javascript" >形式引入js文件,而且引入的越来越多。下面我们就来简单讨论在每个页面引入公共脚本库的统一方式,而不用每个页面都是很多<script src="http://t.zoukankan.com/..." type="text/javascript" >的形式。
和我们以前的做法一样,定义一个页面基类叫BasePage,事件和方法如下:

asp.net简单实现利用HttpModule实现防sql注入第9张asp.net简单实现利用HttpModule实现防sql注入第10张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='http://t.zoukankan.com/{0}' type='text/javascript'></script>", path);
        }

        
#endregion
    }
}

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

免责声明:文章转载自《asp.net简单实现利用HttpModule实现防sql注入》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WCF学习笔记(第一天,1.WCF概述)12个高矮不同的人,排成两排(catalan数)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#-Ftp操作

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System; using System.Collections.Generic; using System.L...

华为机试 计算字符个数

题目描述 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。 输入描述: 第一行输入一个有字母和数字以及空格组成的字符串,第二行输入一个字符。 输出描述: 输出输入字符串中含有该字符的个数。 示例1 输入 ABCDEF A 输出 1 sing System; using Syste...

ZeroMQ示例(C/C++/PHP)详解三种模式

源自:https://blog.csdn.net/qq_16836151/article/details/521081521、应答模式2、均衡分配模式(推拉模式)3、发布订阅模式(天气预报) 提问-回答 让我们从简单的代码开始,一段传统的Hello World程序。我们会创建一个客户端和一个服务端,客户端发送Hello给服务端,服务端返回World。下文是...

3DESC加密算法

3DESC 请求参数和响应参数全采用3des加密规则,由于我是用.NET对接的,而第三方是Java开发的,所以两种程序之间采用的算法有一点差异,java的3des加密采用的是"DESede/CBC/PKCS5Padding"规则,所以对应的C#规则是"PaddingMode.PKCS7和CipherMode.CBC",使用CBC模式的话在C#下必须传入加密...

CString转string

如题,找了半天。。。 1 //CString转string 2 3 USES_CONVERSION; 4 CString temp; 5 temp = _T("kjdsaflkjdlfkj"); 6 char* s_char = W2A(temp); 7 string ss = s_char;...

go语言——实现函数名到函数处理的映射关系(反射的应用)

模拟这样一个场景:当我们知道我们要执行操作的名字,让其作为参数传入,如何通过这个名字取执行相应的函数处理呢? 解决方法:(这里设定一个结构A,其变量a,实现相应函数为fun1、fun2)   ①:首先在编码过程中,我们可以将相应的处理函数进行“同一结构”实现,让其函数名和相应处理函数用map结构形成映射;   ②:通过创建该结构体的变量,通过反射(vf :...