0%

浏览器解析与编码

浏览器解析过程

浏览器的解析可以分为3步,

1
2
3
HTML解析(HTML解析器)
JS解析(JavaScript解析器)
URL解析(URL解析器)

这三个解析器协调工作,当浏览器接受到一个HTML文档时,自上而下进行渲染和解析,首先会触发HTML解析器对文档进行词法分析,完成html解码和dom树建立。接着js解析器接入开始对内联的脚本进行解析,包括解码操作。如果浏览器需要URL上下文,url解析器也会介入开始解析解码。URL解析会根据文档中URL的实际位置不同而在不同的时间解析,例如遇到Onclick事件需要触发才会执行的代码会跳过,等到事件被触发时才会被解析

upload successful

浏览器会解析三个东西:

1
2
3
(1) HTML/SVG/XHTML,解析这三种文件会产生一个 DOM Tree。 
(2) CSS,解析 CSS 会产生 CSS 规则树。
(3) Javascript脚本,主要是通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree.(其中javascript脚本的执行会阻碍dom树的建立,待脚本执行完成后,再接着建立后面的dom树)

示例

upload successful

1
2
3
4
5
6
7
1. 位置:T3qui1a’s item, 浏览器在解析这个位置的字符串时,会对其进行一次HTML解码,(HTML编码、解码)

2. 位置:T3qui1a\’s onclick,浏览器会对其进行:1) 先做HTML解码 2)再做JS解码

3. 位置: //www.knownsec.com,浏览器会对其进行:URL解码

4. 位置:knownsec's url, 浏览器会对此位置字符串进行:1)先JavaScript解码 2)后URL解码

浏览器编码

URL编码:一个百分号和该字符的ASCII编码所对应的2位十六进制数字,例如“/”的URL编码为%2F(一般大写,但不强求)

HTML实体编码:命名实体:以&开头,分号结尾的,例如“<”的编码是“&lt;”

字符编码:十进制、十六进制ASCII码或unicode字符编码,样式为“&#数值;”,例如“<”可以编码为“&#060;”和“&#x3c;”

JS编码:js提供了四种字符编码的策略,

1
2
3
4
1、三个八进制数字,如果不够个数,前面补0,例如“e”编码为“\145”
2、两个十六进制数字,如果不够个数,前面补0,例如“e”编码为“\x65”
3、四个十六进制数字,如果不够个数,前面补0,例如“e”编码为“\u0065”
4、对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)

复合编码:所谓复合编码,也就是说输出的内容输出在多个环境中,例如

1
<td onclick=”openUrl(add.do?userName=’<%=value%>’);”>11</td>

value的内容首先出现在一个URL中,这个URL在一段javascript中,而javascript代码又是html的一部分。所以解码的顺序就是HTML解码–>js解码–>url解码,那么正确的编码顺序就应该是url编码–>js编码–>html编码。

示例

upload successful

先分析一下$name的环境,$name先在html环境中,然后在javascript环境(onclick事件)中,浏览器解析的顺序是html解码–>js解码,所以我们将javascript:alert(/xss/)进行html编码,从而可以绕过限制(当然此处代码还有其他好几种绕过的方式,此处只是简单说明编码问题),因为在javascript解码时,$name已经被html解码了,那么处在javascript中的$name变量就是正常的js代码。

总结

1.通过DOM操作HTML时,可以使用

1
<script>alert(/xss/)

来代替

1
<script>alert(/xss/)</script>

因为DOM会自动补全。

2.innerHTML只能使用

1
<img  src=1 onerror=alert(1)>

这种方式来触发JS。而不能以

1
<script>alert(1)</script>

来触发,因为这种压根不会执行

1
<script>..</script>

之间的内容。

3.javascript伪协议不能被url编码。

4.在解析渲染的过程中,当遇到点是在标签的属性里面时,是会继续渲染,等待渲染完成后,再回朔,调用js解释器执行属性里面的js语句,并不会造成渲染阻塞情况。

5.渲染阻塞的原因是因为浏览器需要一个稳定的DOM树结构,而JS中很有可能有 代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修 改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。

6.对于通用属性的编码方式不适用于href、src、style、事件处理函数(onclick、onmouseover等),因为本身这些属性是支持伪协议的,该编码无效。

7.编码的顺序和解码解析的顺序正好相反