当前位置: 首页 > 图文教程 > 网络编程 > ASP > SQL关于特殊字符处理的基本方法

ASP
ASP基础讲座(下)
解决IIS5 HTTP500内部错误
ASP 3.0高级编程(四十六)
ASP 3.0高级编程(四十五)
ASP 3.0高级编程(四十四)
ASP 3.0高级编程(四十三)
ASP 3.0高级编程(四十二)
ASP 3.0高级编程(四十一)
ASP 3.0高级编程(三十九)
ASP 3.0高级编程(三十八)
ASP 3.0高级编程(三十七)
ASP 3.0高级编程(三十六)
ASP 3.0高级编程(三十五)
ASP 3.0高级编程(三十四)
ASP 3.0高级编程(三十三)
ASP 3.0高级编程(三十二)
ASP 3.0高级编程(三十一)
ASP错误代码说明
jscript错误代码及相应解释大全
ASP错误处理

ASP 中的 SQL关于特殊字符处理的基本方法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 66 ::
收藏到网摘: n/a

一定要对用户可能输入的诸如引号,尖括号等特殊字符给予足够重视,它们可能引发严重的安全问题。SQL注入的基本手法之一,就是利用对单引号未加过滤的安全漏洞。

用户的输入无非两个用途:对数据库操作或显示在页面上,下面分别对这两种情况下特殊字符的处理加以说明。

1. 对数据库操作
用户输入的数据用于对数据库进行操作时,又分为两种情况,一是进行写库操作,二是作为查询条件。

1.1 写库操作
(insert及update都视为写库操作,这果以insert为例说明,update的处理相同)
一般采用insert语句或AddNew方法两种方式进行写库操作,我们先来看insert语句:
DIM username,sqlstr
username = trim(Request.Form("uname"))
sqlstr = "insert into [userinfo] (username) values ('"& username &"')"

以SQL Server为例,使用这种方式写库,如果username中含用单引号('),会出错。使用下面的自定义函数,可以将单引号进行转换:
Rem 转换SQL非法字符
function SQLEncode(fString)
if isnull(fString) then
SQLEncode = ""
exit function
end if
SQLEncode=replace(fString,"'","''")
end function

以上函数将一个单引号转换为两个连续的单引号,数据库能够接受,并以一个单引号写入。SQL语句改为:
sqlstr = "insert into [userinfo] (username) values ('"& SQLEncode(username) &"')"

再来看AddNew方法:
DIM username
username = trim(Request.Form("uname"))
'MyRst为Recordset对象,MyConn为Connection对象
MyRst.open "[userinfo]",MyConn,0,3
MyRst.AddNew
MyRst("username").Value = username
MyRst.Update
MyRst.Close

使用这种方式写库时,不必调用SQLEncode()对单引号进行转换,数据库会自行处理。

对于存储过程的的参数,同样不必进行单引号的转换。

建议大家利用存储过程进行操作,好处嘛,我在《ASP与存储过程》一文中已做了阐述。否则,建议使用AddNew方法写库,好处不仅仅在于避免对单引号进行处理,本文对此不作深入探讨。

1.2 用户输入做为查询条件
如果用户输入的数据作为查询条件出现在where子句中,不论该where子句属于update语句、delete语句还是select语句,都要对单引号进行转换。

2. 用户输入的数据作为输出,显示在页面上
我们这里只讨论不允许用户使用HTML代码的情况,也就是说,即使用户输入了HTML代码,这些数据也不会以HTML代码的形式显示。至于允许用户使用HTML代码的情况,比较复杂,以后专文探讨。

用户输入的数据是绝对不可以不加处理,原样显示的。如果其中包含HTML或js代码,使你的页面混乱不堪倒是小事,甚至可以格掉你的硬盘。

输出显示在页面上的数据,有可能是用户的直接输入,或是取自数据库。可以看到以上在入库时的处理只是转换了单引号,对尖括号,双引号等特殊字符并未处理,我们放在输出的时候再进行处理。

ASP中的server.HTMLEncode()方法可以将许多字符转换为“HTML字符”,如将<转换为<,将>转换为>等等。

在数据显示在页面上之前,可以用server.HTMLEncode()对其进行转换。但是该方法不会对回车,空格进行转换,这样就造成以下问题:如果用户是通过textarea控件输入的数据,输出时将不会保留原有格式,不仅没有回车换行,多个空格也只会显示为一个。为了解决这个问题,我们使用以下自定义函数:
Rem 转换HTML非法字符,用于输出显示时
function HTMLEncode(fString)
if not isnull(fString) then
fString = Replace(fString, ">", ">")
fString = Replace(fString, "<", "<")
fString = Replace(fString, CHR(34), """) '双引号
fString = Replace(fString, CHR(39), "'") '单引号
fString = Replace(fString, CHR(32)&CHR(32), "  ") '空格
fString = Replace(fString, CHR(9), " ") 'tab键值
fString = Replace(fString, CHR(10), "<br>") '换行
fString = Replace(fString, CHR(13), "") '回车
HTMLEncode = fString
end if
end function

调用以上函数,输出通过textarea控件输入的数据,会得到满意的结果。

如果数据输出在表单控件中,不论是何种控件,都可利用server.HTMLEncode()方法转换字符,即使是对于textarea控件,也不会产生问题。虽然回车空格没有被转换,但在该控件中可以被识别。但是,server.HTMLEncode()方法不转换单引号。所以,控件的值一定要使用双引号:
<input type=text name=uname value=""" & server.HTMLEncode(username) & """>

否则,如果用户输入的是 '' onclick=javascript:.... ,以上代码将显示为:
<input type=text name=uname value='' onclick=javascript:...>

而javascript命令可以做的事情实在是太多了。

以上,通过用户输入数据的两种用途,对特殊字符的处理做了大概的说明。还有一种情况:用户的输入作为GET请求的参数值。比如通过以下URL向服务器发送请求:test.asp?username=MyName

我一般只把数值型的数据做此类提交,并在接收时对数据类型做验证。若是字符型的数据,如何处理特殊字符呢?有兴趣的朋友思考一下吧,呵呵。

有些朋友喜欢用JAVAScript过滤特殊字符,而且限制输入的字符很多。我不建议这么做,一是JAVAScript是客户端运行的,不可靠。要知道,对服务器的请求是可以伪造的,伪造者可不会加上你的JAVAScript代码;二是JAVAScript不太友好;三者,实际上没有必要限制那么多字符,限制太多,用户会害怕的。

总结一下我对特殊字符处理的经验吧:

1. 对接收到的数据类型进行验证;
2. 尽量通过存储过程对数据库进行操作;
3. 如上一点不可行,尽量使用AddNew方法写库;
4. 对作为查询条件的数据,使用自定义函数SQLEncode()转换单引号;
5. 表单控件的值,一定要用双引号引起来;
6. 在表单控件中显示数据时,使用server.HTMLEncode()方法转换字符;
7. 对于通过textarea提交的数据,使用自定义函数HTMLEncode()转换字符并保持格式;
8. 尽量避免使用Request()接收数据,应使用Request.Form()或Request.QueryString();
9. 尽量避免通过URL传递字符参数(只用此方式传递数值参数)