LEXSS: 绕过词法解析过程中的安全机制
字数 1988 2025-08-05 08:19:26
LEXSS: 绕过词法解析过程中的安全机制 - 深入教学文档
1. 关键概念介绍
LEXSS(Lexical Parsing XSS)是一种利用HTML解析器与净化型词法解析器之间的解析差异来实现的跨站脚本攻击技术。这种攻击的核心在于欺骗净化型解析器,使其将恶意代码误认为无害的文本数据。
前置知识要求:
- 熟悉XSS(跨站脚本)基本原理
- 了解HTML基本结构和解析过程
- 了解常见的XSS防御措施
2. XSS防御措施概述
2.1 正则表达式过滤(不推荐)
早期防御措施,通过正则表达式匹配和删除危险字符串(如<script>)。易被绕过,例如:
<scRipt>alert(1)</scRipt>
2.2 上下文输出编码
将特殊字符转换为HTML实体编码:
<→<>→>
现代前端框架(ReactJS、Angular等)默认采用此方式。
2.3 词法解析(本文重点)
复杂XSS防御手段,通过分析数据是指令还是文本来实现过滤。常用于:
- 富文本编辑器(TinyMCE、Froala)
- 电子邮件客户端
- HTML净化库(DOMPurify)
3. HTML解析器工作原理
3.1 解析流程
- 网络阶段:输入作为字节传输给解析器
- 分词器阶段(词法解析):
- 分离文本数据与计算机指令
- 根据元素切换上下文状态
- 树形结构阶段:构建DOM树
- 脚本执行阶段:JavaScript修改DOM
- DOM阶段:最终文档对象模型
3.2 上下文状态
HTML解析器在不同元素下会切换解析状态:
| 元素 | 上下文状态 | 示例 |
|---|---|---|
<title>, <textarea> |
RCDATA | <textarea><img src=x></textarea> |
<style>, <xmp>, <iframe> |
RAWTEXT | <xmp></xmp> |
<script> |
脚本数据状态 | - |
<noscript> |
条件RAWTEXT | - |
<plaintext> |
PLAINTEXT | - |
| 其他元素 | 数据状态 | `` |
关键点:只有数据状态会执行指令,其他状态将内容视为文本。
3.3 命名空间混淆
HTML解析器可在三种命名空间间切换:
- HTML(默认)
- MathML
- SVG
当遇到<svg>或<math>标签时,解析器会切换到相应命名空间,可能导致意外行为。
4. 净化型词法解析器工作流程
- 浏览器HTML解析器首次解析用户数据
- 词法解析器分析和过滤数据
- 浏览器HTML解析器再次解析处理后的数据
漏洞根源:两次解析不一致,导致净化解析器误判内容性质。
5. 实际案例分析
5.1 TinyMCE XSS (CVE-2020-12648)
Payload:
<iframe><textarea></iframe>
攻击原理:
<iframe>将上下文切换为RAWTEXT<textarea>进一步切换为RCDATA- 净化解析器误判``位于安全上下文中
- 实际DOM解析时,``位于可执行上下文中
5.2 Froala XSS (CVE-2021-28114)
Payload:
<math><iframe><!--</iframe>
攻击原理:
<math>切换到MathML命名空间- Froala解析器不理解MathML,丢弃
<math>标签 - 剩余内容被误判为注释
- 最终HTML解析器正确解析并执行payload
6. 防御措施
6.1 开发建议
- 确保净化解析器与HTML解析器对数据的理解完全一致
- 考虑元素顺序和嵌套上下文的影响
- 不需要MathML/SVG时,应将其列入黑名单
6.2 补丁策略
- 定期更新使用的库(TinyMCE、Froala等)
- 及时应用安全补丁
6.3 内容安全策略(CSP)
实施严格的CSP策略:
- 避免
unsafe-inline和unsafe-eval - 限制脚本来源
7. 测试方法论
- 使用各种命名空间和上下文切换元素进行模糊测试
- 重点关注:
<iframe>,<textarea>,<xmp>等状态切换元素<math>和<svg>命名空间元素
- 记录所有解析差异
- 根据差异构造利用链
8. 总结
LEXSS攻击利用了HTML解析器与净化解析器之间的细微差异,通过精心构造的HTML元素序列和命名空间混淆,绕过词法解析安全机制。防御此类攻击需要深入理解HTML解析过程,并确保净化逻辑与浏览器解析逻辑完全一致。