The important thing in life is to have a great aim , and the determination
导航
BlogJava
首页
新随笔
联系
聚合
管理
<
2011年1月
>
日
一
二
三
四
五
六
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
留言簿
(7)
给我留言
查看公开留言
查看私人留言
随笔分类
IT技术相关(63)
(rss)
投资理财(10)
(rss)
数据库(22)
(rss)
生活相关(8)
(rss)
随笔档案
2020年3月 (1)
2019年5月 (1)
2017年8月 (2)
2017年7月 (6)
2017年5月 (1)
2017年4月 (1)
2016年3月 (1)
2015年9月 (1)
2015年8月 (1)
2015年7月 (1)
2014年6月 (1)
2014年5月 (22)
2013年7月 (1)
2011年12月 (5)
2011年11月 (1)
2011年10月 (13)
2011年9月 (1)
2011年3月 (2)
2011年2月 (2)
2011年1月 (2)
2010年12月 (1)
2010年8月 (2)
2010年7月 (3)
2009年11月 (1)
2009年10月 (1)
2009年9月 (1)
2009年8月 (4)
2009年5月 (1)
2008年12月 (1)
2008年11月 (4)
2008年10月 (7)
2008年3月 (1)
2008年1月 (4)
2007年12月 (2)
2007年6月 (1)
2007年5月 (7)
2007年4月 (14)
2007年3月 (22)
2007年2月 (2)
2007年1月 (2)
2006年12月 (24)
2006年11月 (5)
文章档案
2019年8月 (1)
2014年4月 (3)
相册
最近的我
阅读排行榜
1. 在SQL Server中通过SQL语句实现分页查询(8882)
2. Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法 (7797)
3. 修改TabHost默认样式(文字居中)(5982)
4. IText使用PDF模板输出报表的实践(转)(4508)
5. 特殊字符的转义(3844)
评论排行榜
1. 各种数据库取表前N条记录的写法(1)
2. 数据仓库建模与ETL实践技巧(转载)(1)
3. 自定义处理JS的空格(1)
4. JAVA实现四舍五入的方法(0)
5. 数据仓库逻辑建模 (0)
常用链接
我的随笔
我的评论
我的参与
最新评论
统计
随笔 - 178
文章 - 3
评论 - 5
引用 - 0
IT技术链接
博客园--专注于.NET技术
51CTO技术园地
Ajax程序设计入门
DB2 9 基础(730 考试)认证指南
DB2 9 数据库管理(731考试)认证指南系列教程
EOS基础开发
ITPUB论坛
IT专家网
JavaEye技术社区
JAVA开源文档
JBPM@javaEye技术网
Spring完美进阶
万达信息股份有限公司
中文JAVA网站
北京东华合创数码科技股份有限公司
广东省专业资格考试网
张龙(风中叶)的专栏
数据仓库之路论坛
新技术天空_ntsky
李静瑶lijingyao8206
王珊教授个人网页
相关技术资料下载
竹笋炒肉:正则表达式学习笔记
胡长城个人主页
蓝杰javaFound
面向构件与SOA专区
保险相关
中国人保寿险有限公司
保险产品展览
友情链接
dracularking的专栏
Drate的博客
e代剑客——温柔一刀博客
Habitat Framework
soleghost的专栏
世纪佳缘
冯强的CSDN博客
唐艳明博客
太阳雨博客
姝佳博园
小孙空间
崔慧QQ空间
李阳新浪博客
清茶漫语
王老师博客
王菲菲
玻璃心的空间
白色恋月空间
离尘冰雪博客
胡长城博客
花生油QQ空间
花香蝶自来-学无止境博客
财税分析师沙龙的BLOG
雨松MOMO的程序世界专栏
基金知识
一、基金相关概念
三、基金运作
二、基金费用
华夏基金理财教育专区
基金买卖网
基金网
广州妈妈网—生活理财篇
开放基金净值预测
招商证券牛网
晨星公司
理财村长博客
财帮子社区
生活相关
1010Job工作网
女人的秘密
招商银行
搏彩资料
最新评论
1. re: 数据仓库建模与ETL实践技巧(转载)[未登录]
写的非常好,拜读了!
--google
2. re: 各种数据库取表前N条记录的写法
美神恶魔
--伊珊
3. re: 自定义处理JS的空格
str.trim()
--韩现龙未登录
4. re: 寂寞不归路-软件高手是这样练成的(转载 来源:希赛网)
Good
--姜利阳
5. re: 如何作好软件项目的分析(转载希赛网)
考验综合能力的时候
--姜利阳
特殊字符的转义
特殊字符转义
由于 Web 应用程序需要联合使用到多种语言,每种语言都包含一些特殊的字符,对于动态语言或标签式的语言而言,如果需要动态构造语言的内容时,一个我们经常会碰到的问题就是特殊字符转义的问题。下面是 Web 开发者最常面对需要转义的特殊字符类型:
HTML 特殊字符;
JavaScript 特殊字符;
SQL 特殊字符;
如果不对这些特殊字符进行转义处理,则不但可能破坏文档结构,还可以引发潜在的安全问题。Spring 为 HTML 和 JavaScript 特殊字符提供了转义操作工具类,它们分别是 HtmlUtils 和 JavaScriptUtils。
HTML 特殊字符转义
HTML 中 <,>,& 等字符有特殊含义,它们是 HTML 语言的保留字,因此不能直接使用。使用这些个字符时,应使用它们的转义序列:
&:&
" :"
< :<
> :>
由于 HTML 网页本身就是一个文本型结构化文档,如果直接将这些包含了 HTML 特殊字符的内容输出到网页中,极有可能破坏整个 HTML 文档的结构。所以,一般情况下需要对动态数据进行转义处理,使用转义序列表示 HTML 特殊字符。下面的 JSP 网页将一些变量动态输出到 HTML 网页中:
清单
1
. 未进行 HTML 特殊字符转义处理网页
<%@ page language=
"java"
contentType=
"text/html; charset=utf-8"
%>
<%!
String userName =
"</td><tr></table>"
;
String address =
" \" type=\"button"
;
%>
<table border=
"1"
>
<tr>
<td>姓名:</td><td><%=userName%></td> ①
</tr>
<tr>
<td>年龄:</td><td>
28
</td>
</tr>
</table>
<input value=
"<%=address%>"
type=
"text"
/> ②
在 ① 和 ② 处,我们未经任何转义处理就直接将变量输出到 HTML 网页中,由于这些变量可能包含一些特殊的 HTML 的字符,它们将可能破坏整个 HTML 文档的结构。我们可以从以上 JSP 页面的一个具体输出中了解这一问题:
<table border=
"1"
>
<tr>
<td>姓名:</td><td></td><tr></table></td>
① 破坏了 <table> 的结构
</tr>
<tr>
<td>年龄:</td><td>
28
</td>
</tr>
</table>
<input value=
" "
type=
"button"
type=
"text"
/>
② 将本来是输入框组件偷梁换柱为按钮组件
融合动态数据后的 HTML 网页已经面目全非,首先 ① 处的 <table> 结构被包含 HTML 特殊字符的 userName 变量截断了,造成其后的 <table> 代码变成无效的内容;其次,② 处 <input> 被动态数据改换为按钮类型的组件(type=
"button"
)。为了避免这一问题,我们需要事先对可能破坏 HTML 文档结构的动态数据进行转义处理。Spring 为我们提供了一个简单适用的 HTML 特殊字符转义工具类,它就是 HtmlUtils。下面,我们通过一个简单的例子了解 HtmlUtils 的具体用法:
清单
2
. HtmpEscapeExample
package
com.baobaotao.escape;
import
org.springframework.web.util.HtmlUtils;
public
class
HtmpEscapeExample {
public
static
void
main(String[] args) {
String specialStr =
"<div id=\"testDiv\">test1;test2</div>"
;
String str1 = HtmlUtils.htmlEscape(specialStr); ①转换为HTML转义字符表示
System.out.println(str1);
String str2 = HtmlUtils.htmlEscapeDecimal(specialStr); ②转换为数据转义表示
System.out.println(str2);
String str3 = HtmlUtils.htmlEscapeHex(specialStr); ③转换为十六进制数据转义表示
System.out.println(str3);
④下面对转义后字符串进行反向操作
System.out.println(HtmlUtils.htmlUnescape(str1));
System.out.println(HtmlUtils.htmlUnescape(str2));
System.out.println(HtmlUtils.htmlUnescape(str3));
}
}
HTML 不但可以使用通用的转义序列表示 HTML 特殊字符,还可以使用以 # 为前缀的数字序列表示 HTML 特殊字符,它们在最终的显示效果上是一样的。HtmlUtils 提供了三个转义方法:
方法 说明
static
String htmlEscape(String input) 将 HTML 特殊字符转义为 HTML 通用转义序列;
static
String htmlEscapeDecimal(String input) 将 HTML 特殊字符转义为带 # 的十进制数据转义序列;
static
String htmlEscapeHex(String input) 将 HTML 特殊字符转义为带 # 的十六进制数据转义序列;
此外,HtmlUtils 还提供了一个能够将经过转义内容还原的方法:htmlUnescape(String input),它可以还原以上三种转义序列的内容。运行以上代码,您将可以看到以下的输出:
str1:<div id=
"testDiv"
>test1;test2</div>
str2:<div id=
"testDiv"
>test1;test2</div>
str3:<div id=
"testDiv"
>test1;test2</div>
<div id=
"testDiv"
>test1;test2</div>
<div id=
"testDiv"
>test1;test2</div>
<div id=
"testDiv"
>test1;test2</div>
您只要使用 HtmlUtils 对代码 清单
1
的 userName 和 address 进行转义处理,最终输出的 HTML 页面就不会遭受破坏了。
JavaScript 特殊字符转义
JavaScript 中也有一些需要特殊处理的字符,如果直接将它们嵌入 JavaScript 代码中,JavaScript 程序结构将会遭受破坏,甚至被嵌入一些恶意的程序。下面列出了需要转义的特殊 JavaScript 字符:
' :\'
" :\"
\ :\\
走纸换页: \f
换行:\n
换栏符:\t
回车:\r
回退符:\b
我们通过一个具体例子演示动态变量是如何对 JavaScript 程序进行破坏的。假设我们有一个 JavaScript 数组变量,其元素值通过一个 Java List 对象提供,下面是完成这一操作的 JSP 代码片断:
清单
3
. jsTest.jsp:未对 JavaScript 特殊字符进行处理
<%@ page language=
"java"
contentType=
"text/html; charset=utf-8"
%>
<jsp:directive.page
import
=
"java.util.*"
/>
<%
List textList =
new
ArrayList();
textList.add(
"\";alert();j=\""
);
%>
<script>
var txtList =
new
Array();
<%
for
(
int
i =
0
; i < textList.size() ; i++) { %>
txtList[<%=i%>] =
"<%=textList.get(i)%>"
;
① 未对可能包含特殊 JavaScript 字符的变量进行处理
<% } %>
</script>
当客户端调用这个 JSP 页面后,将得到以下的 HTML 输出页面:
<script>
var txtList =
new
Array();
txtList[
0
] =
""
;alert();j=
""
; ① 本来是希望接受一个字符串,结果被植入了一段JavaScript代码
</script>
由于包含 JavaScript 特殊字符的 Java 变量直接合并到 JavaScript 代码中,我们本来期望 ① 处所示部分是一个普通的字符串,但结果变成了一段 JavaScript 代码,网页将弹出一个 alert 窗口。想像一下如果粗体部分的字符串是“
";while(true)alert();j="
”时会产生什么后果呢?
因此,如果网页中的 JavaScript 代码需要通过拼接 Java 变量动态产生时,一般需要对变量的内容进行转义处理,可以通过 Spring 的 JavaScriptUtils 完成这件工作。下面,我们使用 JavaScriptUtils 对以上代码进行改造:
<%@ page language=
"java"
contentType=
"text/html; charset=utf-8"
%>
<jsp:directive.page
import
=
"java.util.*"
/>
<jsp:directive.page
import
=
"org.springframework.web.util.JavaScriptUtils"
/>
<%
List textList =
new
ArrayList();
textList.add(
"\";alert();j=\""
);
%>
<script>
var txtList =
new
Array();
<%
for
(
int
i =
0
; i < textList.size() ; i++) { %>
① 在输出动态内容前事先进行转义处理
txtList[<%=i%>] =
"<%=JavaScriptUtils.javaScriptEscape("
"+textList.get(i))%>"
;
<% } %>
</script>
通过转义处理后,这个 JSP 页面输出的结果网页的 JavaScript 代码就不会产生问题了:
<script>
var txtList =
new
Array();
txtList[
0
] =
"\";alert();j=\""
;
① 粗体部分仅是一个普通的字符串,而非一段 JavaScript 的语句了
</script>
SQL特殊字符转义
应该说,您即使没有处理 HTML 或 JavaScript 的特殊字符,也不会带来灾难性的后果,但是如果不在动态构造 SQL 语句时对变量中特殊字符进行处理,将可能导致程序漏洞、数据盗取、数据破坏等严重的安全问题。网络中有大量讲解 SQL 注入的文章,感兴趣的读者可以搜索相关的资料深入研究。
虽然 SQL 注入的后果很严重,但是只要对动态构造的 SQL 语句的变量进行特殊字符转义处理,就可以避免这一问题的发生了。来看一个存在安全漏洞的经典例子:
SELECT COUNT(userId)
FROM t_user
WHERE userName=
'"+userName+"'
AND password =
'"+password+"'
;
以上 SQL 语句根据返回的结果数判断用户提供的登录信息是否正确,如果 userName 变量不经过特殊字符转义处理就直接合并到 SQL 语句中,黑客就可以通过将 userName 设置为 “
1
' or '
1
'='
1
”绕过用户名/密码的检查直接进入系统了。
所以除非必要,一般建议通过 PreparedStatement 参数绑定的方式构造动态 SQL 语句,因为这种方式可以避免 SQL 注入的潜在安全问题。但是往往很难在应用中完全避免通过拼接字符串构造动态 SQL 语句的方式。为了防止他人使用特殊 SQL 字符破坏 SQL 的语句结构或植入恶意操作,必须在变量拼接到 SQL 语句之前对其中的特殊字符进行转义处理。Spring 并没有提供相应的工具类,您可以通过 jakarta commons lang 通用类包中(spring/lib/jakarta-commons/commons-lang.jar)的 StringEscapeUtils 完成这一工作:
清单
4
. SqlEscapeExample
package
com.baobaotao.escape;
import
org.apache.commons.lang.StringEscapeUtils;
public
class
SqlEscapeExample {
public
static
void
main(String[] args) {
String userName =
"1' or '1'='1"
;
String password =
"123456"
;
userName = StringEscapeUtils.escapeSql(userName);
password = StringEscapeUtils.escapeSql(password);
String sql =
"SELECT COUNT(userId) FROM t_user WHERE userName='"
+ userName +
"' AND password ='"
+ password +
"'"
;
System.out.println(sql);
}
}
事实上,StringEscapeUtils 不但提供了 SQL 特殊字符转义处理的功能,还提供了 HTML、XML、JavaScript、Java 特殊字符的转义和还原的方法。如果您不介意引入 jakarta commons lang 类包,我们更推荐您使用 StringEscapeUtils 工具类完成特殊字符转义处理的工作。
posted on 2011-01-24 14:16
鸿雁
阅读(3844)
评论(0)
编辑
收藏
所属分类:
IT技术相关
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
相关文章:
POI操作Excel
python操作文件存在的问题解决办法
Hadoop-2.4.1学习之QJM HA的自动故障转移
Yarn 调度器Scheduler详解
hive大数据倾斜总结
HIVE和HBASE区别
Hive分布式安装配置Hive+Mysql
TCP/UDP区别以及UDP如何实现可靠传输
一文读懂分布式数据库Hbase
在python中获取mac和ip地址
Powered by:
BlogJava
Copyright © 鸿雁