从程序员角度谈谈xss攻击的防御
2016-10-04 00:00
295 查看
摘要: xss攻击的本质是html注入,核心原因是代码与数据没有做好隔离,防御的方式是根据每一种注入的场景,针对性的进行过滤,防止将数据误作为代码执行。
一个jsp页面:
如果username值为
个人感觉xss攻击,可以理解为html注入,是属于注入攻击的一种,出现在两种执行语法的交界处。换句话说,就是一个字符串在一种语言是一种标准的字符串,但是到了另外一种语言执行,就变成代码的一部分了。也就是代码和数据没有隔离好。
按照上面的例子可以这样理解,<script>alert('xss')</script>字符串在jsp中就是一个字符串,但是到了html页面解析执行时,这个字符串已经变成html的一个语法结构,已经不是一串单纯的字符串了。
注意一下,所有两种执行语法交界处都可能发生注入攻击。但是事实上我们常听到的注入攻击只有两种,html注入和sql注入。为什么前端数据转为http请求,以及http请求转为后台语言数据时都没有注入攻击的说法呢?因为浏览器对数据做了过滤,防止了注入攻击,对开发者和用户都是透明的。
防御注入攻击的方式只有一种就是字符过滤,但是因为不同语法的解析规则都不一样,所以不存在通用的注入防御规则,因为针对一种语法的防御到另外一种语法中就不适用了。
输入过滤有一个比较麻烦的问题。当用户输入敏感字符时,输入过滤后,可能导致用户输入的字符串变成另外的字符串。举个例子来说:
一个用户的用户名为 hell"o ,输入过滤时,是要将 " 过滤为 " ,那么上个例子中的输出就会变为 hell"o发表了评论 ,用户名无欲无故多了,如果”过滤为 " ,那么js变量中用户名却变成 hell "o,这个也会很奇怪。
所以通常防御xss攻击时采用输出过滤的方式,在需要的地方进行过滤。
输入过滤一般只是使用在富文本中。
##html标签中输出
需要进行htmlEncode。即将var变量中的 <>/'"&空格 全部转化成html特殊字符。
##html标签属性中输出
进行htmlEncode。
##script标签中输出
使用JavascriptEncode。
##在事件中输出
处理方式和<script>中类似,使用JavascriptEncode
##css中输出
尽量少在css中输出,如果必须使用OWASP ESAPI的encodeForCss函数。
###在地址中输出
使用URLEncode。可以防止一下情况的出现:
对于
需要做两种处理。
判断是否采用http协议开头,否就强制加上。
然后采用URLEncode。
##过滤规则说明
以上提到的过滤规则都是出自OWASP ESAPI这个项目,参考https://www.owasp.org/index.php/OWASP_Java_Encoder_Project#tab=Use_the_Java_Encoder_Project,感兴趣的可以自行百度谷歌一下,这里不展开了。
参考的资料:《白帽子讲web安全》
#xss攻击的简介
xss即跨站脚本攻击(Cross Site Scripting),本质是html注入,核心原因是代码与数据没有做好隔离。举个例子来说:一个jsp页面:
<span> <%=username%>发表了评论 </span>
如果username值为
<script>alert('xss')</script>,就会发现页面发生了注入攻击。本来预料的
用户X发表了评论字符没有出现,反而弹出了警告框。
个人感觉xss攻击,可以理解为html注入,是属于注入攻击的一种,出现在两种执行语法的交界处。换句话说,就是一个字符串在一种语言是一种标准的字符串,但是到了另外一种语言执行,就变成代码的一部分了。也就是代码和数据没有隔离好。
按照上面的例子可以这样理解,<script>alert('xss')</script>字符串在jsp中就是一个字符串,但是到了html页面解析执行时,这个字符串已经变成html的一个语法结构,已经不是一串单纯的字符串了。
注意一下,所有两种执行语法交界处都可能发生注入攻击。但是事实上我们常听到的注入攻击只有两种,html注入和sql注入。为什么前端数据转为http请求,以及http请求转为后台语言数据时都没有注入攻击的说法呢?因为浏览器对数据做了过滤,防止了注入攻击,对开发者和用户都是透明的。
防御注入攻击的方式只有一种就是字符过滤,但是因为不同语法的解析规则都不一样,所以不存在通用的注入防御规则,因为针对一种语法的防御到另外一种语法中就不适用了。
#防御xss攻击的方式
防御xss攻击的方式就是字符过滤,过滤的时机有两个:输入过滤和输出过滤。输入过滤有一个比较麻烦的问题。当用户输入敏感字符时,输入过滤后,可能导致用户输入的字符串变成另外的字符串。举个例子来说:
一个用户的用户名为 hell"o ,输入过滤时,是要将 " 过滤为 " ,那么上个例子中的输出就会变为 hell"o发表了评论 ,用户名无欲无故多了,如果”过滤为 " ,那么js变量中用户名却变成 hell "o,这个也会很奇怪。
所以通常防御xss攻击时采用输出过滤的方式,在需要的地方进行过滤。
输入过滤一般只是使用在富文本中。
#输出过滤
本节主要是介绍所有html注入的地方,以及每种位置需要进行的过滤规则。最后简单介绍每种过滤规则的实现原理。##html标签中输出
<div><%=var %></div>
需要进行htmlEncode。即将var变量中的 <>/'"&空格 全部转化成html特殊字符。
##html标签属性中输出
<div id="" name="<%=var %>" ></div>
进行htmlEncode。
##script标签中输出
<script>var x="<%=var %>";</script>
使用JavascriptEncode。
##在事件中输出
<a href=# onclick="funcA('<%=var %>')" > test</a>
处理方式和<script>中类似,使用JavascriptEncode
##css中输出
<div style="background:url(javascript:alert('xss'))"></div>
尽量少在css中输出,如果必须使用OWASP ESAPI的encodeForCss函数。
###在地址中输出
<a href="http://www.test.com?test=<%=var %>" />
使用URLEncode。可以防止一下情况的出现:
<a href="http://www.test.com?test=" onclick=alert(1) " />
对于
<a href="<%=var %>" />
需要做两种处理。
判断是否采用http协议开头,否就强制加上。
然后采用URLEncode。
##过滤规则说明
以上提到的过滤规则都是出自OWASP ESAPI这个项目,参考https://www.owasp.org/index.php/OWASP_Java_Encoder_Project#tab=Use_the_Java_Encoder_Project,感兴趣的可以自行百度谷歌一下,这里不展开了。
#总结
以上还没提到如何进行富文本的过滤,因为参考的是owasp的antiSamy项目,也是一个很大的项目,抽空就这内容单独介绍一下。参考的资料:《白帽子讲web安全》
相关文章推荐
- 关于AngularJS 1.x 从Flex程序员角度谈谈我的一些看法(一)
- 关于AngularJS 1.x 从Flex程序员角度谈谈我的一些看法(二)
- 谈谈系统中的耦合以及从另一个角度来解释姜同学的疑虑
- 从程序员的角度看ASCII, GB2312, UNICODE, UTF-8
- 【转】从JVM内存管理的角度谈谈静态方法和静态属性
- 程序员趣味读物:谈谈Unicode编码
- 从事ASP.NET开发两年多,谈谈对两三年工作经验的ASP.NET程序员的基本见解
- 谈谈嵌入式程序员的发展方向
- 从程序员角度看ELF
- 程序员趣味读物:谈谈Unicode编码
- 从程序员的角度来看为什么我们需要工作流
- 从程序员角度理解磁盘分区(MBR和GPT)
- 聊聊阿里社招面试,谈谈“野生”Java程序员学习的道路
- XSS攻击与防御
- xss攻击与防御
- 一个工作三年左右的Java程序员跟大家谈谈从业心得
- 从面试官的角度谈谈大数据面试
- 谈谈移动应用设计——从一个普通开发者的角度
- 公司技术管理角度看C++游戏程序员发展
- 利用HttpOnly来防御xss攻击