起因

深入研究这个SVG黑魔法大概用了我三个多小时的时间,起因是@陈硕小伙伴问了我一个XSS相关的问题,让我很感兴趣,随后就深入研究了一下,整个过程很辛苦,但也很有趣。 :)

疑问

陈硕给了我两个代码,问我为什么一个可以执行,另一个不可以执行。

1、可以执行XSS的代码:
<svg><script>alert&#40;1)</script>

如图:
SVG XSS的一个黑魔法

2、不可以执行XSS的代码:
<script>alert&#40;1)</script>

那么问题来了,为什么加了<svg>的可以执行?

顺腾摸瓜

@陈硕给了我一篇深入理解浏览器解析机制和XSS向量编码让我参考。

其中提到在HTML中有五类元素:

  1. 空元素(Void elements),如<area>,<br>,<base>等等

  2. 原始文本元素(Raw text elements),有<script><style>

  3. RCDATA元素(RCDATA elements),有<textarea><title>

  4. 外部元素(Foreign elements),例如MathML命名空间或者SVG命名空间的元素

  5. 基本元素(Normal elements),即除了以上4种元素以外的元素

五类元素的区别如下:

  1. 空元素,不能容纳任何内容(因为它们没有闭合标签,没有内容能够放在开始标签和闭合标签中间)。

  2. 原始文本元素,可以容纳文本。

  3. RCDATA元素,可以容纳文本和字符引用。

  4. 外部元素,可以容纳文本、字符引用、CDATA段、其他元素和注释

  5. 基本元素,可以容纳文本、字符引用、其他元素和注释

按照文章中提到的html解析流程,解析到<svg>的时候会变成标签开始状态(Tag open state),然后到标签名状态(Tag name state),等等,最终到数据状态(Data state),并释放当前标签的token,当解析器处于数据状态(Data state)时,它会继续解析,每当发现一个完整的标签,就会释放出一个token。

恍然大悟

按照上面的逻辑并没有什么问题,但是主要问题是为什么XSS代码执行了?

随后在网上看了很多很多资料,查阅过的资料我会写到文章最后的参考里面

在深入理解浏览器解析机制和XSS向量编码我们已经可以知道,svg属于外部元素,也就是Foreign elements
whatwg中也有提到。

  • Foreign elements
    Elements from the MathML namespace and the SVG namespace.

可见Foreign elemnts来源于MathMLSVG命名空间。

MathML指的是什么?

SVG XSS的一个黑魔法

XML啊!!XML啊!!XML啊!!

那么我猜,<svg>遵循XMLSVG的定义。

我们知道,在XML中,&#40;会被解析成

  • 在XML中实体会自动转义,除了<![CDATA[]]>包含的实体

代码:

<xml>
    <name>aaa</name>
    <value>aaaaaaa&#40;</value></xml>

如图:

SVG XSS的一个黑魔法

当然,SVG标准中也定义了script标签的存在。

SVG XSS的一个黑魔法

所以,这个XSS之所以能够执行是因为遵循了svg及xml的标准

总结&随便说点什么

学XSS还是要深入了解原理啊!这里的原理指的不仅仅是js代码,各种事件等等,而应该更深层次的去理解。