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. 相关内容
  3. 3. 为什么实体编码会被解析
  4. 4. 挑战赛答案
  5. 5. 延伸
  6. 6. 参考资料