深入理解XSS编码--浏览器解析原理(1)
字数 1716 2025-08-29 08:31:47
深入理解XSS编码与浏览器解析原理
浏览器解析HTML的基本原理
浏览器本质上是一个解释器,其工作流程类似于编译器:
- 浏览器(如IE)通过
mshtml.dll解析HTML文本 - 遇到
<符号时开始解析元素定义,直到>或匹配的结束标签 - 将每个HTML元素视为对象,属性作为对象的成员变量
- JavaScript代码由
Jscript9.dll(IE)或其他JS引擎解释执行
HTML中的特殊字符处理
在HTML中,某些字符具有特殊含义(如<, >, "等),需要使用实体编码来表示:
<input value="te>st" /> <!-- 使用>表示>字符 -->
XSS中触发JavaScript执行的三种主要场景
1. <script>标签内
- 浏览器直接将
<script>标签内的内容原封不动传递给JS引擎 - 编码处理:不做任何解码处理,所有编码形式由JS引擎处理
- 示例:
<script>\x97lert(1);</script> <!-- 直接传递给JS引擎 -->
2. JavaScript伪协议(javascript:)
- 形式:
<a href="javascript:alert(1)"> - 编码处理:
- 首先进行URL解码
- 然后进行HTML实体解码
- 示例:
<a href="javascript:%61%6c%65%72%74%28%31%29"> <!-- URL编码会被解码 -->
3. 事件处理器(on*属性)
- 形式:
<button onclick="alert(1)"> - 编码处理:
- 只进行HTML实体解码
- 其他编码形式(如Unicode、Hex等)不会被解码
- 示例:
<button onclick="alert(1)"> <!-- 实体编码会被解码 --> <button onclick="alert('\u0031')"> <!-- Unicode编码不会被HTML解析器解码 -->
不同场景下的编码有效性分析
| 序号 | 示例代码 | 是否有效 | 原因分析 |
|---|---|---|---|
| 1 | <a href="javascript:%61%6c%65%72%74%28%32%29"> |
Y | URL编码被解码 |
| 2 | <a href="javascript%3aalert(3)"></a> |
N | :被URL编码,不被识别为协议 |
| 3 | <div></div> |
Y | 正常事件处理 |
| 4 | <textarea><script>alert(5)</script></textarea> |
N | script标签作为文本内容 |
| 5 | <button onclick="confirm('7');">Button</button> |
Y | 实体编码被解码 |
| 6 | <button onclick="confirm('8\u0027);">Button</button> |
N | 事件处理器不解析Unicode |
| 7 | <script>alert(9);</script> |
Y | 直接传递给JS引擎 |
| 8 | <script>\u0061\u006c\u0065\u0072\u0074(10);</script> |
Y | JS引擎解析Unicode |
| 9 | <script>alert('13\u0027)</script> |
Y | JS引擎解析Unicode |
高级分析与结论
-
HTML解析器:
- 只识别和处理HTML实体编码
- 不处理JavaScript特有的编码形式(如
\x,\u等)
-
JavaScript引擎:
- 处理JavaScript特有的编码形式
- 包括Unicode转义(
\uXXXX)、Hex转义(\xXX)等
-
URL解析:
- 在javascript:伪协议中,先进行URL解码
- 然后进行HTML实体解码
-
防御本质:
- 所有注入漏洞都源于数据与指令的混淆
- 根本解决方案是实现数据与指令的严格分离
实际应用建议
-
在
<script>标签内:- 可以使用JS支持的各类编码
- 但HTML实体编码无效
-
在事件处理器中:
- 只能使用HTML实体编码
- JS编码无效
-
在javascript:伪协议中:
- 可以组合使用URL编码和HTML实体编码
- 但协议标识符(
javascript:)不能被编码
-
测试XSS时:
- 应根据上下文选择合适的编码方式
- 避免盲目尝试各种编码组合
理解这些原理可以帮助安全研究人员更有效地测试XSS漏洞,也有助于开发人员实施更精确的防御措施。