目录
在解析一篇HTML文档时主要有三个处理过程:HTML解析,URL解析和JavaScript解析。
第一题
<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29"></a>
执行结果
经过urlcode解码后为"javascript(1)",但是返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
在<a>标签的href属性里面没有HTML编码内容,所以不考虑。其中href内部是URL,于是直接丢给URL模块处理,但是协议无法被识别(即被编码的javascript:),解码失败,因此不会被执行。
URL规定协议,用户名,密码都必须是ASCII,编码当然就无效了。
第二题
<a href="javascript:%61%6c%65%72%74%28%32%29">
执行结果
在 : 前面经过HTML解码后为"javascript",后面经过urlcode解码之后为"alert(2)",返回的结果是:The javascript will execute.
原理
那为什么这次就能执行呢?
先HTML解码,得到
<a href="javascript:%61%6c%65%72%74%28%32%29">
href中为URL,URL模块可识别为javascript协议,再进行URL解码,得到
<a href="javascript:alert(2)">
由于是javascript协议,解码完成后交给JS模块处理,于是被执行。
第三题
<a href="javascript%3aalert(3)"></a>
执行结果
经过urlcode解码后为" : ",返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
协议名是javascript:,将" : "编译了。其中href内部是URL,于是直接丢给URL模块处理,但是协议无法识别,解码失败,不会被执行。(原理同第一题一样)
第四题
<div><img src=x onerror=alert(4)></div>
执行结果
经过HTML解码后为"<"和">",返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
这里包含了HTML编码内容,HTML编码就是为了显示这些特殊字符,而不干扰正常的DOM解析,所以这里面的内容不会变成一个img元素,也不会被执行。
从HTML解析机制来看,在读取<div>之后进入数据状态,<会被HTML解码,但不会进入标签开始状态,当然也就不会创建img元素,也就不会执行。
第五题
<textarea><script>alert(5)</script></textarea>
执行结果
经过HTML解码后为"<"和">",返回的结果是:The javascript will not execute and the character entities will not be decoded either.
原理
为什么不能执行呢?
<textarea>是RCDATA元素,RCDATA只能容纳文本和字符引用,注意不能容纳其他元素,HTML解码得到
<textarea><script>alert(5)</script></textarea>
虽然HTML实体编码被解析了,但是不能进入到"标签开始状态",因此不会被执行。
第六题
<textarea><script>alert(6)</script></textarea>
执行结果
返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
<textarea>是RCDATA元素,在RCDATA元素中有个特殊情况,当在浏览器解析RCDATA元素的过程中,解析器会进入"RCDATA状态"。在这个状态中,如果遇到"<"字符,它会转换到"RCDATA小于号状态"。如果"<"字符后没有紧跟着"/"和对应的标签名,解析器会转换回“RCDATA状态”。这意味着在RCDATA元素标签的内容中(例如<textarea>或<title>的内容中),唯一能够被解析器认做是标签的就是“</textarea>”或者"</title>"。因此,在"<textarea>"和“<title>”的内容中不会创建标签,就不会有脚本能够执行。
第七题
<button onclick="confirm('7');">Button</button>
执行结果
经过HTML解码后为 ' ,返回的结果是:The javascript will execute.
原理
为什么能够执行呢?
这里onclick中为标签的属性值(类比第二题中的href),所以会被HTML解码,得到
<button onclick="confirm('7');">Button</button>
然后被执行
第八题
<button onclick="confirm('8\u0027);">Button</button>
执行结果
经过Unicode解码为 ' ,返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
onclick中的值会交给JS处理,在JS中只有字符串和标识符能够用Unicode表示,换句话说就是JS不能编码符号('、"、(、)等等),'显然不行,所以JS执行会失败。
什么是标识符呢?
代码中用来表示变量、函数、或属性的字符序列。
在JavaScript中,标识符只能包含字母或数字或下划线("_")或美元符号("$"),且不能以数字开头。标识符与字符串不同之处在于字符串是数据,而标识符是代码的一部分。在Javascript中,无法将标识符转换为字符串,但有时可以将字符串解析为标识符。
第九题
<script>alert(9);</script>
执行结果
经过HTML解码后为alert(9),返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
script 属于原始文本元素(Raw text elements),只可以容纳文本,注意没有字符引用,于是直接由JS处理,但是JS也认不出来,执行失败。
原始文本元素(Raw text elements)有<script>和<style>
第十题
<script>\u0061\u006c\u0065\u0072\u0074(10);</script>
执行结果
经过Unicode解码后为alert,返回的结果是:The javascript will execute.
原理
为什么能够执行呢?
在JS中Unicode编码可以被HTML文本直接解析,除了符号不能够被解析,因此可以执行。
第十一题
<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>
执行结果
经过Unicode解码后为alert(11),返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
在JS中只有字符串和标识符能够用Unicode表示,因为其中()被Unicode编码了,因此不能够被解析,所以不能执行。
第十二题
<script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>
执行结果
经过Unicode解码后为alert和12,返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
这里很多人就会怀疑,虽然这里看似没什么毛病,但是这里\u0031\u0032在解码的时候会被解码为字符串12,注意是字符串,不是数字,文字显示是需要引号的,因此JS执行失败。
第十三题
<script>alert('13\u0027)</script>
执行结果
经过Unicode解码为 ' ,返回的结果是:The javascript will not execute.
原理
为什么不能执行呢?
在JS中只有字符串和标识符能够用Unicode表示,因为其中 ' 被Unicode编码了,因此不能够被解析,所以不能执行。
第十四题
<script>alert('14\u000a')</script>
执行结果
经过Unicode解码为\n也就是换行,执行的结果是:The javascript will execute.
原理
为什么能够执行呢?
Java菜鸡都知道在Java里\u000a是换行,相当于在源码里直接按一下回车键,后面的代码都换行了,但是并没有编码任何东西,因此可以执行。
第十五题
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
执行结果
返回的结果是:The javascript will execute.
原理
为什么能够执行呢?
解码过程为:
先HTML解码,得到
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
再href中有URL模块处理,解码得到
<a href="javascript:\u0061\u006c\u0065\u0072\u0074(15)"></a>
最终识别JS协议,然后由JS模块处理,解码得到
<a href="javascript:alert(15)"></a>
最后被执行