您的位置:首页 > 理论基础 > 计算机网络

通过HttpModule实现数据库防注入

2006-05-24 14:14 423 查看

通过HttpModule实现数据库防注入

昨天刚把数据库防注入的原型发了上去,发觉好像还漏了点东西,现在把它全部补上.
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------------------------

1

using System;
2

using System.Web;
3

namespace 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



SQL注入式攻击代码分析#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,完成!

源码下载: http://www.cnblogs.com/Files/S.Sams/SqlstrAny.rar

发表于 2006-04-18 10:35 S.Sams 阅读(240) 评论(4) 编辑 收藏 收藏至365Key 所属分类: ASP.NETC#



评论

楼主思路是好的,但说句实话,这样处理这些字符太弱智了点

and count这些都直接去掉是不是有欠考虑

我就曾发现有个论坛连发文章都不能包括这些关键字

blueeeeeee 评论于 2006-04-21 13:48 回复

# re: 通过HttpModule实现数据库防注入
这只是一个思路,完成可以可以再把字符做一下编码处理同样也可以达到你的目的.
如: and = and 即 and在网页显示的是and
select = select

实际就是做16进制编码, 这样实现起来会更科学. 可以保持原有的内容一致的情况下实现防SQL注入!
S.Sams 评论于 2006-04-26 18:49 回复

# re: 通过HttpModule实现数据库防注入
字符做一下编码处理 如何赋值?/
flyfish 评论于 2006-04-28 20:51 回复

# re: 通过HttpModule实现数据库防注入
类似这种处理方式

for(int i=0;i<System.Web.HttpContext.Current.Request.Form.Count;i++)

getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i]; // 这是当前键值.

System.Web.HttpContext.Current.Request.QueryString[getkeys] // 获取该键值的值. 直接处理即可.

处理方式: select = select;

ASP.NET 防止SQL注入式攻击

using System;

namespace Theme.Services.Public
{
/// <summary>
/// SqlstrAny 的摘要说明。
/// </summary>
public class ProcessRequest
{
public ProcessRequest()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

#region SQL注入式攻击代码分析
/// <summary>
/// 处理用户提交的请求
/// </summary>
public void StartProcessRequest()
{
try
{
string getkeys = "";
string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["CustomErrorPage"].ToString();
if (System.Web.HttpContext.Current.Request.QueryString != null)
{

for(int i=0;i<System.Web.HttpContext.Current.Request.QueryString.Count;i++)
{
getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i];
if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys]))
{
System.Web.HttpContext.Current.Response.Redirect (sqlErrorPage+"?errmsg=sqlserver&sqlprocess=true");
System.Web.HttpContext.Current.Response.End();
}
}
}
if (System.Web.HttpContext.Current.Request.Form != null)
{
for(int i=0;i<System.Web.HttpContext.Current.Request.Form.Count;i++)
{
getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i];
if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys]))
{
System.Web.HttpContext.Current.Response.Redirect (sqlErrorPage+"?errmsg=sqlserver&sqlprocess=true");
System.Web.HttpContext.Current.Response.End();
}
}
}
}
catch
{
// 错误处理: 处理用户提交信息!
}
}
/// <summary>
/// 分析用户请求是否正常
/// </summary>
/// <param name="Str">传入用户提交数据</param>
/// <returns>返回是否含有SQL注入式攻击代码</returns>
private bool ProcessSqlStr(string Str)
{
bool ReturnValue = true;
try
{
if (Str != "")
{
string SqlStr = "and |exec |insert |select |delete |update |count | * |chr |mid |master |truncate |char |declare ";
string[] anySqlStr = SqlStr.Split('|');
foreach (string ss in anySqlStr)
{
if (Str.IndexOf(ss)>=0)
{
ReturnValue = false;
}
}
}
}
catch
{
ReturnValue = false;
}
return ReturnValue;
}
#endregion

}
}

// System.Configuration.ConfigurationSettings.AppSettings["CustomErrorPage"].ToString(); 这个为用户自定义错误页面提示地址,
//在Web.Config文件时里面添加一个 CustomErrorPage 即可
//<!-- 防止SQL数据库注入攻击的出错页面自定义地址 -->
// <add key="CustomErrorPage" value="../Error.html" />

# re: 通过HttpModule实现数据库防注入
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: