Learning Man's Blog

SVG with HTML Parsing

字数统计: 1.2k阅读时长: 4 min
2019/08/07

DEMO

<script>alert&#40;1)</script>
<svg>
  <script>alert&#40;2)</script>
</svg>

一句话总结:HTML 在解析 svg 节点下的 script 时,会暂停原有html标准解析,并使用xml标准解析svg-script,导致了实体引用被解析执行。

另外可查到的相关问题:Why does this XSS vector work in svg but not in HTML?

相关内容

html element

在 html 中分为五类元素

  • Void elements:空元素
    area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr
  • Raw text elements:原始文本元素
    script, style
  • RCDATA elements: RCDATA元素
    textarea, title
  • Foreign elements:外部元素
    MathML命名空间、SVG命名空间中的元素.
  • Normal elements:基本元素
    除了以上提到的元素以外的其他元素

区别如下:

  • 空元素:不能容纳任何内容(因为没有闭合标签(end tag),所以无法在开始标签和闭合标签中间防止内容)
  • 原始文本元素:可以容纳Unicode字符组成的文本,但不允许包含</开头的一系列内容
  • RCDATA元素:可以容纳text 以及字符引用,但不能含有意义不明的&符号,除此外同上不允许包含</开头的一系列内容
  • 外部元素:当开始标签自动闭合时,不能包含任何内容(因为没有结束标签(end tag),所以不能在开始标签和结束标签之间放内容),当开始标签不自闭合时,其内容可以包含文本、字符引用、CDATA块、其他元素和注释,但是文本不能包含编码为U+003C的小于符号(<)或者意义不明的&符号
  • 基本元素:可以包含文本、字符引用、其他元素以及注释,但是文本不能包含编码为U+003C的小于符号(<)或者意义不明的&符号。在内容模型和本章节的给出的限制之外,有些常规元素在可以包含的内容方面有额外的限制

剩下内容可见参考资料[1]一篇很好的文章

HTML script parse

html词法解析文档:html parsing

在接收到 script 标签后,进入script data state(脚本数据状态)

-w554

继续往下跟随,会发现怎么都无法进入Character reference state(字符引用状态),即无法解析被实体化编码后的内容

-w617

簡單總結一下,當<script>沒有做編碼時,會將script整體作爲一個token釋放,然後就會進入script data state狀態;但是如果編碼後,就會將script看成文本,拆成一個一個字符釋放(轉義後爲s作爲token釋放,又進入字符引用狀態,繼續轉義後爲c作爲token釋放,……,最後是t),所以到最後也沒進入script data state狀態,也就是沒有執行環境。

要想执行 script 意味着必须要在data state状态下跟入script标签进入script data stat

data state + <script> -> script data state

那肯定就会有人问为什么 Unicode 编码可以呢
因为这又涉及了 JavaScript 标准(JavaScript 是由 Ecma 标准化的,标准叫 ECMAScript)

这里可以看到 JS 允许标识符名称使用 Unicode 字符,支持Unicode转义字符\u000A\u000B,但不支持Unicode转义序列串\u000A000B,具体规则可以去看一下

-w753

这样就能理解为什么下面的代码会执行了

<script>\u0061\u006c\u0065\u0072\u0074(10);</script>

实际感觉多读读标准文档理解渲染机制就能解决很多问题

script in svg

简单看一下就大致能明白主体意思

-w1593

为什么实体编码会被解析

经过查找后,发现还存在一个 vxml,形式上和 svg 有些类似,但是在 vxml-script 中的 Html 实体编码就不会被解析出来

如果说 <svg> 是满足 xml 和 svg,利用 svg 支持 script,xml 支持实体编码,那么为什么类似的<vxml>不行呢?

在 html 解析文档中可以看到这个内容,当 script 标签节点出现在 svg 节点时,会挂起 html解析并根据 svg 标准进行进一步解析,这就导致了实体引用被解码

html解析 -> 发现svg-script -> svg(xml)解析 -> html解析继续

-w1306

挑战赛答案

https://rozna.reqresp.io/uti?name=%3Csvg%3E%26%2334%3B%3balert%26%2340%3bdocument.cookie)%3b%26%2334%3B

延伸

Content-Type:application/xml

<script xmlns="http://www.w3.org/2000/svg">alert&#40;1)</script>

参考资料

  1. 强推:https://www.twblogs.net/a/5d15ae1bbd9eee1e5c82750e
  2. ※ 原文:https://www.attacker-domain.com/2013/04/deep-dive-into-browser-parsing-and-xss.html
  3. 译文:http://bobao.360.cn/learning/detail/292.html
CATALOG
  1. 1. DEMO
  2. 2. 相关内容
    1. 2.1. html element
    2. 2.2. HTML script parse
    3. 2.3. script in svg
  3. 3. 为什么实体编码会被解析
  4. 4. 挑战赛答案
  5. 5. 延伸
  6. 6. 参考资料