XXE 是什么
XXE(XML 外部实体注入)出现在解析不可信 XML 的场景:多数 XML 解析器默认允许在文档类型定义中声明外部实体,如果解析配置未做限制,构造的文档就能让解析器去读取本地文件、发起内网请求,甚至通过实体嵌套造成拒绝服务。危险点在于「解析不可信输入」这个动作本身,所以防护的方向有两层——能改用 JSON 等纯数据格式就不用 XML,必须解析 XML 时显式关闭外部实体与 DTD 处理。
基本信息
| 风险类别 | OWASP Top 10 2021 A05 安全配置错误;CWE-611 |
|---|---|
| 触发点 | 解析用户 XML 的入口:SOAP、SVG 上传、Office 文档解析、RSS 处理 |
| 危害 | 文件读取、SSRF、拒绝服务 |
| 防护 | 禁用 DTD 与外部实体(解析器配置);能用 JSON 就不用 XML |
| 范围要求 | 覆盖所有解析入口,包括旁路与预览功能 |
| 验证方式 | 构造无害测试文档确认外部实体不被解析 |
典型场景
- SOAP 与 XML-RPC 接口接收外部请求体
- 图片与矢量图上传:SVG 本质是 XML 文档
- 文档处理:Office 与 PDF 的元数据解析
- 订阅与集成:RSS、Atom 与第三方 XML 数据源
- 配置导入导出:以 XML 作为配置文件格式
- 报表与模板引擎:以 XML 作为模板语言
排查面
排查面
检索代码中的 XML 解析器初始化点
确认是否设置 disallow-doctype-decl 等安全属性
SVG 与 Office 文档解析库同样需要安全模式
# 常见语言的安全开关:
# Java:工厂类关闭外部实体与 DTD 处理
# Python:lxml 禁用实体解析;defusedxml 提供安全封装
# PHP:libxml_disable_entity_loader 在旧版本中需要显式设置风险形态与影响
| 形态 | 说明 | 影响 |
|---|---|---|
| 本地文件读取 | 实体指向本机文件路径 | 配置文件与凭据泄露 |
| 内网请求 | 实体指向内网地址 | 内网探测与服务调用 |
| 拒绝服务 | 实体嵌套与膨胀 | 解析耗尽内存与 CPU |
| 盲注利用 | 响应不回显内容 | 通过错误与外带通道判断结果 |
部分语言的默认解析配置本身不安全;升级依赖不会自动修复配置问题,需要显式设置。
把安全解析封装成统一入口是长期方案:所有业务都调用同一个封装函数,避免每处解析各自配置、逐步腐化。