浏览器解码看XSS
字数 1607 2025-08-26 22:11:57
浏览器解码机制与XSS攻击防御详解
浏览器解码规则概述
浏览器在处理网页内容时遵循严格的解码顺序:
- HTML解析器对HTML文档进行解析,完成HTML解码并创建DOM树
- JavaScript或CSS解析器对内联脚本进行解析,完成JS/CSS解码
- URL解码根据URL所在顺序不同,可能在JS解码前或解码后进行
HTML编解码机制
HTML解析器工作原理
HTML解析器作为状态机,从输入流获取字符并按规则转换状态。遇到<符号(后面没有/)会进入"标签开始状态",经过一系列状态转换后进入"数据状态"并释放当前标签的token。
HTML元素分为五类:
- 空元素(Void elements):如
<area>,<br>,<base>等,不能容纳内容 - 原始文本元素(Raw text elements):
<script>和<style> - RCDATA元素(RCDATA elements):
<textarea>和<title> - 外部元素(Foreign elements):如MathML或SVG命名空间的元素
- 基本元素(Normal elements):除以上4种外的其他元素
HTML解码关键点
- 在"数据状态(Data state)"下进行HTML编码
- 示例:
<h1>hhhhh</h1>无法解析<h1>hhhhhhhhh</h1>能正确解析
- RCDATA元素(
<textarea>和<title>)中的字符引用会被HTML解析器解码 - 在RCDATA元素中,只有
</textarea>或</title>会被识别为标签
SVG元素的特殊性
<svg>遵循XML和SVG定义规则:
- 在XML中,
(会被解析成( - XML中实体会自动转义,除了
<![CDATA[和]]>包含的实体
JavaScript编解码机制
JS编码规则
- 对除阿拉伯数字和字母外的所有内容进行编码
- 常用Unicode转义序列如
\uXXXX(如<的Unicode编码为\u003c)
JS解码关键点
-
单引号、双引号和圆括号等控制字符编码后将无法识别
- 错误示例:``
- 正确示例:``
-
编码顺序影响:
- 先JS编码再HTML解码:
浏览器:HTML解码 → JS解码 → 执行
- 先JS编码再HTML解码:
-
开发中的常见漏洞:
- 仅使用HTML实体编码防御XSS不足
- 示例漏洞:
- 攻击者可输入:
");alert("test然后HTML编码绕过
正确防御方法
应先进行JavaScript编码,再进行HTML编码:
- 服务器看到的内容应为JS编码后的形式
- HTML解码后变为JS编码形式
- JavaScript解析器工作时,控制字符仅被解析为标识符名称或字符串
URL编解码机制
URL解码顺序示例
<a href="javascript:alert(3)">hhhhh<a>
浏览器处理顺序:
- 看到
<标签 → HTML解码 - 看到
href→ URL解码 - 看到
javascript→ JS解码
攻击编码步骤
- 先进行JS编码:
<a href="javascript:\u0061\u006c\u0065\u0072\u0074(3)">hhhhhh</a> - 再进行URL编码:
<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(3)">hhhhhh</a> - 最后进行HTML编码
复杂场景示例
<a onclick="window.open('value1')" href="javascript:window.open(value2)">
-
value1处理顺序:
- HTML解码
- JS解码
- URL解码
-
value2处理顺序:
- HTML解码
- URL解码
- JS解码
- URL解码
总结与防御建议
-
理解浏览器解码机制是XSS攻击和防御的基础
-
不同上下文需要采用不同的编码策略
-
单一编码方式无法全面防御XSS
-
推荐防御策略:
- 在HTML上下文中:先JS编码,再HTML编码
- 在URL上下文中:注意解码顺序,采用多层编码
- 在JS上下文中:严格控制输入,使用专用编码函数
-
开发注意事项:
- 不要仅依赖HTML实体编码
- 根据输入点的上下文选择合适的编码方式
- 测试各种编码组合的解析结果