`
werr1985
  • 浏览: 67664 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

阅读更多

一定要对用户可能输入的诸如引号,尖括号等特殊字符给予足够重视,它们可能引发严重的安全问题。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()方法不转换单引号。所以,控件的值一定要使用双引号: Webjx.Com

<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传递字符参数(只用此方式传递数值参数)


************************************************************
SQL查询中的特殊字符处理

我们都知道SQL查询过程中,单引号“'”是特殊字符,所以在查询的时候要转换成双单引号“''”。

但这只是特殊字符的一个,在实际项目中,发现对于like操作还有以下特殊字符:下划线“_”,百分号“%”,方括号“[]”以及尖号“^”。

其用途如下:

下划线:用于代替一个任意字符(相当于正则表达式中的 ? )

百分号:用于代替任意数目的任意字符(相当于正则表达式中的 * )

方括号:用于转义(事实上只有左方括号用于转义,右方括号使用最近优先原则匹配最近的左方括号)

尖号:用于排除一些字符进行匹配(这个与正则表达式中的一样)

以下是一些匹配的举例,需要说明的是,只有like操作才有这些特殊字符,=操作是没有的。

a_b...        a[_]b%



a%b...       a[%]b%



a[b...       a[[]b%



a]b...       a]b%



a[]b...      a[[]]b%



a[^]b...     a[[][^]]b%



a[^^]b...    a[[][^][^]]b%



在实际进行处理的时候,对于=操作,我们一般只需要如此替换:

' -> ''

对于like操作,需要进行以下替换(注意顺序也很重要)



[ -> [[]     (这个必须是第一个替换的!!)



% -> [%]    (这里%是指希望匹配的字符本身包括的%而不是专门用于匹配的通配符)



_ -> [_]



^ -> [^]

注意:

在Oracle9i中,经过实际测试发现,需要处理的特殊字符有:

_(下划线)

%(百分号)

‘(单引号)

&(这个在Oracle中与后面的字符组成变量)

上面其他字符不需要处理。

对于前三种,需要使用ESCAPE进行转义,对于’&‘符号比较特殊,需要将’xxx&xxx'转化为'xxx&' || 'xxx'的形式,或者用chr(38)表示’&‘

转义符最好使用‘、‘(反斜线)。

使用’@‘,在全角字符过长时会发生错误,原因目前不明。

数据库sql的特殊字符:

1)单引号’:例如string a = “this is marry’s book.”;

             使用insert时就会出错。

             解决:a= a.Replace("'","''");

2)百分号% :例如string a = “50%”;

             使用like查询,查出带有50%的所有记录,则会被认为是通配符。

             解决:Select * FROM tbl where name LIKE '%/%%' ESCAPE '/'

即a=a.Replace("%","/%%")

或者[%]

3)下划线_ :例如 string a = “m_n”;

              使用like查询,select * from tbl where name like ‘%m_n%’,下划线被认为是通配符。

              解决:[_]

 

4)方括号[]:主要是左括号:[[]

5)尖括号^:[^]

分享到:
评论
1 楼 zjshan 2010-08-26  
描述的很详细,用惯了Hibernate就很少关注这些东西了,今天正好需要做jdbc特殊字符处理。

相关推荐

    SQL关于特殊字符处理的基本方法.doc

    SQL 关于特殊字符处理的基本方法 SQL 关于特殊字符处理的基本方法是 SQL 编程中非常重要的一方面。特别是在用户输入方面,可能会包含一些特殊字符,例如引号、尖括号等,这些字符可能会引发严重的安全问题,如 SQL ...

    C#实现过滤sql特殊字符的方法集合

    在C#中,防止SQL注入攻击的一个重要方法是过滤SQL特殊字符。SQL注入是一种常见的网络安全威胁,通过在用户输入的数据中插入恶意SQL语句,攻击者可以操纵数据库,获取、修改或删除敏感信息。以下是一些C#中过滤SQL...

    SqlServer自定义字符聚合

    标题“SqlSserver自定义字符聚合”所指向的知识点主要是关于如何在SQL Server中创建和使用自定义聚合函数,特别是在处理字符串数据时的特殊需求。自定义字符聚合允许开发者根据业务需求定制特定的聚合逻辑,比如实现...

    表单的验证数字字符特殊符号

    本主题主要关注的是“表单的验证数字字符特殊符号”,这涉及到对用户在表单中输入的数字、字母以及特殊字符的检查。 一、表单验证的重要性 表单验证可以防止无效数据的提交,减少服务器端的处理负担,提高用户体验...

    PHP与SQL Server处理维吾尔文的方法研究.pdf

    1. PHP与SQL Server交互中的字符集问题:在PHP中,默认访问SQL Server的方式不支持UTF-8字符集,这意味着当处理维吾尔文这样的特殊字符集时会出现问题。维吾尔文是一种拼音文字,有其特殊的书写规则和字符集。 2. ...

    SQL SERVER 双引号问题处理

    ### SQL Server 双引号问题处理 在进行数据库操作时,我们经常需要用到各种各样的字符来构建复杂的查询语句。其中,SQL Server 使用单引号(' ')来标识字符串,这是一种约定俗成的做法。然而,在某些情况下,比如...

    经典SQL脚本大全

    │ │ 3.2 各种字符串分拆处理函数.sql │ │ 3.3 各种字符串合并处理示例.sql │ │ 3.4.1 分段截取函数.sql │ │ 3.4.2 分段更新函数.sql │ │ 3.4.3 IP地址处理函数.sql │ │ 3.5.1 字符串比较函数.sql │ │ ...

    java防sql注入攻击过滤器

    例如,对于SQL关键字和特殊字符进行转义。 4. **异常处理**:当检测到潜在的SQL注入尝试时,过滤器应阻止请求,记录日志,并向用户返回适当的错误信息。 5. **使用预编译的SQL语句(PreparedStatement)**:除了...

    SQL截取字符串函数

    ### SQL截取字符串函数详解 ...通过上述方法和技术,我们可以灵活地处理各种字符串截取的需求,在实际工作中高效地完成数据处理任务。这些函数不仅可以单独使用,还可以根据具体场景组合使用,以满足更加复杂的需求。

    sql语句的基本介绍和用法

    SQL(Structured Query Language)是一种用于管理和处理数据库的标准计算机语言。它主要用于管理关系型数据库中的数据,包括查询、更新、插入和删除等操作。 #### 二、基本SQL语句 在SQL中,有一些最常用的操作语句...

    Transact-SQL基本函数集

    这些Transact-SQL基本函数是处理SQL Server数据库数据的基石,掌握了这些函数的使用,对于数据库管理和数据处理将变得游刃有余。例如,可以计算员工的平均工资、识别工资最高的员工,甚至能够处理文本信息,进行复杂...

    动态SQL语句基本语法.doc

    "动态SQL语句基本语法" 动态SQL语句是SQL语言中的一种特殊语句,能够根据不同的条件和变量生成不同的SQL语句。本文将详细介绍动态SQL...然而,需要正确地处理字符串连接、单引号的使用、输出参数和特殊字符等问题。

    SQL 注入 攻击 测试方法介绍

    1. **输入异常字符**:测试时,可以在输入框中添加特殊字符,如单引号(')、分号(;)或双引号("),查看系统是否能正确处理。例如,输入`admin' --`,如果系统返回错误信息,可能表明存在SQL注入漏洞。 2. **利用逻辑...

    基于SQL Server的SQL注入攻击防范方法.pdf

    【SQL Server的SQL注入攻击防范方法】 SQL注入攻击是一种针对基于SQL Server的Web应用程序的常见安全威胁,通过向应用程序的输入字段中插入恶意SQL代码,攻击者可以绕过权限限制,获取敏感信息,甚至破坏数据库。...

    GKD-PL_SQL引擎中表达式处理模块的设计与实现.pdf

    表达式处理是PL/SQL引擎中最基本且重要的部分。 3. 表达式操作符与函数:PL/SQL语言中的表达式由操作数和操作符组成,包括常见的算术操作符、关系操作符、逻辑操作符,以及PL/SQL特有的操作符,如LIKE、IS NULL、...

    常用的sql防注入代码

    例如,检查输入是否为预期的格式(如电子邮件地址、数字等),或者使用函数如`htmlspecialchars()`(在PHP中)来转义HTML和SQL特殊字符。 4. **使用存储过程**:虽然存储过程本身不能完全防止SQL注入,但它们可以...

    jquery过滤特殊字符',防sql注入的实现方法

    尽管这种方法可以过滤一些常见的特殊字符,但要完全防止SQL注入,还需要更全面的解决方案。例如,使用预编译的SQL语句(如参数化查询或存储过程)可以极大地降低SQL注入的风险。另外,后端服务器应该负责所有的数据...

    sql server 中进行des加密

    C#代码中,使用`DESCryptoServiceProvider`的`CreateEncryptor()`方法获取加密器,然后使用`TransformFinalBlock()`方法对字符串进行加密。加密后的结果通常以Base64编码形式存储,以便在数据库中安全地保存二进制...

    sql 注入 sql injection

    输入验证可以过滤或转义特殊字符;参数化查询确保用户输入作为独立参数处理,而非拼接在SQL语句中;存储过程可减少暴露的SQL代码,提高安全性;ORM框架能自动处理SQL语句,减少直接编写SQL的机会;限制数据库权限只...

Global site tag (gtag.js) - Google Analytics