SQL Injection可以说是当前网络环境中的主流攻击手段之一,如何有效防止脚本注入一直困扰着广大程序设计者。在程序设计中,往往一个小的疏忽,就可能导致系统被注入,甚至带来严重的后果。对于脚本注入,总结起来,有以下两种情况:

过滤策略考虑不周。比如说程序中只过滤了单引号,其实上我们可以饶过单引号继续注入;
过滤变量不全。由于过滤策略只针对具体的单一的变量,往往会漏掉对某些变量的过滤。

本文就是针对上述问题而提出的一种通用的解决方案。

相关知识
在ASP程序数据传递中, 客户端(Browser)向服务器提交请求有三种方法:Head、Get和Post。 通过Header方法,服务器只向客户端返回网页的头信息,而不是数据本身。实际上,数据传递只通过了GET和 POST这两种方法,即在Form表单中Method属性值(缺省为GET)。

假如使用“GET”属性,浏览器将该值绑定在页面所有控件上,成为一个查询字符串,且附在被请求页面的URL上(经过URL编码)。当这个请求到达Web服务器时,其值由ASP的Request.QueryString集合提供。假如设置METHOD属性为“POST”,浏览器将值包装进发送服务器的HTTP报头中,通过Request.Form集合提供给ASP。

经URL编码的字符串长度存在一定的限制,其上限值为1024字节。因此,过长的字符串可能会引起溢出和字符被截掉。同时,查询字符串出现在浏览器的地址栏和所有的保存的链接和收藏夹中。不仅如此,还显露了通过Web服务器时在HTTP请求中不想显示的值,它也可能出现你的服务器和其他路由服务器的日志文件中。而通过POST传递的数值(在HTTP请求报头中的值)是不会出现在日志文件中的。

过滤原理
通过以上的介绍,我们已经知道服务器获取客户端的数据是通过Request.QueryString集合(GET方法)和Request.Form集合(POST方法)来实现的。所以,如果我们在程序中检查Request.QueryString集合和Request.Form集合的值,并过滤掉特殊字符,就达到了字符过滤的目的,而不必针对具体的变量编写程序。实现方法如下:
If Request.Form”" Then
For Each Data In Request.Form
‘对Data应用过滤策略,当出现非法字符时执行相应的处理程序
Next
End If
If Request.QueryString”" Then
For Each Data In Request.QueryString
‘对Data应用过滤策略,当出现非法字符时执行相应的处理程序
Next
End If

通用系统解决方案
由于SQL注入是发生在执行SQL语句的时候,也就是说发生在对数据库操作的页面,所以我们在有数据库操作的页面将从客户端传递来的数据进行过滤,就可以全面防止SQL注入。因此,只需在数据库连接的文件(如:conn.asp)应用过滤策略,就可以达到全面过滤的目的。在实际应用中,我们将过滤策略文件包含到数据库连接的文件中即可。
在实际应用中,我们可以过滤策略(非法字符)存放在数据库中,实现过滤策略的灵活管理。同时,我们可以针对特定的过滤策略,指定相应的处理过程:当出现非法字符时,是停止程序运行还是后台记录,或者是将程序导向错误提示页面;对于后台记录数据,管理员可以查看系统日志,并根据实际情况对访问IP进行封锁;对于IP封锁,我们也可以制定相应的策略,对拨号帐号实行临时封锁,如12小时,对固定IP实行长期封锁等等。

你学会了吗?