0399-mXSS攻击的成因及常见种类

# mXSS攻击的成因及常见种类

0x00 译者的话
———

* * *

本文原文是由国外大牛Mario Heiderich在2013年所写的一篇paper:mXSS attacks: attacking well-secured web-applications by using innerHTML mutations. 本人觉得此类mXSS攻击较为隐蔽,常规的XSS过滤器并不能防止此类攻击。在测试QQ空间日志中的确存在此类问题后,认为mXSS在WEB应用中还是存在较大的潜在危害,因此,决定将此文做一个翻译。但是,一来由于水平有限,仅能依靠自己浅薄的理解来大致的翻译一下,文中图片以及代码都是在自己的理解上加以重新阐述,也许这样更加易于读者掌握。如果英文较好的同学可自行阅读英文原版。二来,我个人仅注重“攻”的一部分,本文中我认为实用性不高的部分,以及如何防御此类攻击的大幅段落,我并未进行翻译,因而有需要的读者也需要自行去了解这些部分。不论如何,希望本文能够让国内的研究者们对mXSS有一个基本的了解。

0x01 简介
——-

* * *

不论是服务器端或客户端的XSS过滤器,都认定过滤后的HTML源代码应该与浏览器所渲染后的HTML代码保持一致,至少不会出现很大的出入(图1)。然而,如果用户所提供的富文本内容通过javascript代码进入innerHTML属性后,一些意外的变化会使得这个认定不再成立:一串看似没有任何危害的HTML代码,将逃过XSS过滤器的检测,最终进入某个DOM节点的innerHTML中,浏览器的渲染引擎会将本来没有任何危害的HTML代码渲染成具有潜在危险的XSS攻击代码。随后,该段攻击代码,可能会被JS代码中的其它一些流程输出到DOM中或是其它方式被再次渲染,从而导致XSS的执行。 这种由于HTML内容进入innerHTML后发生意外变化(mutation,突变,来自遗传学的一个单词,大家都知道的基因突变,gene mutation),而最终导致XSS的攻击流程,被称为突变XSS(mXSS, Mutation-based Cross-Site-Scripting),整个流程的示意图见图2。从流程中不难看出,突变发生在XSS过滤流程之后,因此不论是服务器端还是客户端的XSS过滤器对这类攻击并不能进行有效的防御。

![2014022300123470806.png](http://drops.javaweb.org/uploads/images/d8a687a0d2337dddd8a8d47b8137d10a4d3d722f.jpg)

图1. XSS过滤所假设的前提

![2014022300151189780.png](http://drops.javaweb.org/uploads/images/1e78479e08dfbdefe523e4192168ab663a90c3f7.jpg)

图2. mXSS攻击流程

将内容置于innerHTML这种操作,在现在的WEB应用代码中十分常见,根据原文作者的统计,1W个常见的WEB应用中,大约有1/3使用了innerHTML属性,这将会导致潜在的mXSS攻击。从浏览器角度来讲,mXSS对三大主流浏览器(IE,CHROME,FIREFOX)均有影响。表1列出到目前为止已知的mXSS种类,接下来的部分将分别对这几类进行讨论与说明。建议读者主要使用IE8来测试本文中的代码。具体测试代码如下:

“`

xx
xx

“`

  表1. 本文中所涉及的mXSS种类

| 英文 | 中文 |
| :-: | :-: |
| Backtick Characters breaking Attribute Delimiter Syntax | 反引号打破属性边界导致的 mXSS |
| XML Namespaces in Unknown Elements causing Structural Mutation | 未知元素中的xmlns属性所导致的mXSS |
| Backslashes in CSS Escapes causing String-Boundary Violation | CSS中反斜线转义导致的mXSS |
| Misfit Characters in Entity Representation breaking CSS Strings | CSS中双引号实体或转义导致的mXSS |
| CSS Escapes in Property Names violating entire HTML Structure | CSS属性名中的转义所导致的mXSS |
| Entity-Mutation in non-HTML Documents | 非HTML文档中的实体突变 |
| Entity-Mutation in non-HTML context of HTML documents | HTML文档中的非HTML上下文的实体突变 |

0x02 反引号打破属性边界导致的 mXSS
———————-

* * *

该类型是最早被发现并利用的一类mXSS,于2007年被提出,随后被有效的修复,所以当前绝大多数用户的浏览器不会被此mXSS所影响。当时的利用代码如下:

“`
输入形式:

图片[1]-0399-mXSS攻击的成因及常见种类-棉花糖会员站

突变形式:

``onload=xss()

可以看到,突变后的形式变成了有效的XSS攻击代码。

“`

0x03 未知元素中的xmlns属性所导致的mXSS
————————–

* * *

一些浏览器不支持HTML5的标记,例如IE8,会将article,aside,menu等当作是未知的HTML标签。对于开发者来说,虽然是未知标签,但是我们还是可以通过设置这些标签的xmlns 属性,让浏览器知道这些未知的标签是的XML命名空间是什么。一般来说,在HTML中,指定这些未知标签的xmlns属性并没有任何意义,也不会改变它们在浏览器中的外观之流的东西。但是,这些被指定了xmlns属性的标签进入innerHTML后,被浏览器所渲染,就会发生一些变化,而这个变化被十分猥琐的用于了XSS。首先我们来看正常情况下设置xmlns的情况。

“`
输入形式:

123

突变形式:

123

“`

接着猥琐流很快就会想到下面的代码,可以看出,成功变成了含有onerror=alert(1) 的img标签。

“`
输入形式:

123

突变形式:

123

“`

扩展:细心的同学也许会注意到,我们的代码中,并未闭合标签。那么一个经常碰到的场景是:XSS过滤器会在解析HTML代码时,自动补全未闭合的标签。这样一来,就会出现下面的场景:

“`
输入形式:

123

过滤后形式:

123

突变后形式:

123

“`

聪明的我们应该不难想到应对办法,这应该也就是[http://html5sec.org/?xmlns#97](http://html5sec.org/?xmlns#97)中所描述问题的发现过程(由Silin于2011年发现)。

“`
输入形式:

123

突变后形式: