快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

数据验证之特别字符处理

一定要对用户可能输入的诸如引号,尖括号等特别字符给予足够重视,它们可能引发严峻的安全问题。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字符”,如将<转变为&lt;,将>转变为&gt;等等。
在数据显示在页面上之前,可以用server.HTMLEncode()对其进行转变。但是该方式不会对回车,空格进行转变,这样就造成以下问题:假如用户是通过textarea控件输入的数据,输出时将不会保留原有格式,不仅没有回车换行,多个空格也只会显示为一个。为了解决这个问题,我们使用以下自定义函数:

Rem 转变HTML非法字符,用于输出显示时
function HTMLEncode(fString)
if not isnull(fString) then
fString = Replace(fString, ">", "&gt;")
fString = Replace(fString, "<", "&lt;")
fString = Replace(fString, CHR(34), "&quot;") \\\'双引号
fString = Replace(fString, CHR(39), "&#39;") \\\'单引号
fString = Replace(fString, CHR(32)&CHR(32), "&nbsp; ") \\\'空格
fString = Replace(fString, CHR(9), "&nbsp;") \\\'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传递字符参数(只用此方法传递数值参数)
返回类别: 教程
上一教程: ASP 莫名其妙的错误
下一教程: 有关站内模糊查询的源程序

您可以阅读与"数据验证之特别字符处理"相关的教程:
· 在ASP中处理数据库的NULL记录
· ASP中对数据库表的操作,可使用事务处理,并支持多事务处理
· ASP中处理数据库图像的方式
· ASP与数据库运用:密码验证
· 处理二进制数据
    微笑服务 优质保证 索取样品