XXE:XML 解析器的「默认太信任」

Web安全 · 2 分钟阅读· 353 次阅读

XML 解析器默认允许外部实体,这是历史设计。于是一个看起来无害的「导入 XML」功能,能读出服务器上的文件。

更麻烦的是它可以与 SSRF 组合:用实体发请求,把内网响应带进错误信息里。

先说结论

禁用 DTD 与外部实体,能换 JSON 就换。 配置开关比过滤字符串可靠得多。

  • 解析器显式关闭外部实体与 DTD
  • 不接受用户提供的 DTD
  • 错误信息不回显解析细节
  • 新接口优先 JSON

漏洞是怎么产生的

XXE 的载荷通常藏在 DOCTYPE 里:定义实体指向 file:// 或 http://,然后在文档里引用。

因为解析发生在「业务逻辑之前」,很多输入过滤根本来不及生效。

修复与验证

修复不是改一行代码,而是四件事一起做:

  • 盘点所有 XML 解析点:接口、配置文件、SOAP、Office 文档解析
  • 关闭 DTD 与外部实体(各语言有对应开关)
  • 限制解析深度与实体展开次数,防 billion laughs
  • 错误响应统一化,不回显解析器原始报错
  • 对外接口改用 JSON

攻击面与检测点

按影响面排序,先修影响最大的:

语言 配置 说明
Java disallow-doctype-decl=true 首选彻底禁用
PHP libxml_disable_entity_loader(true) 老版本必需
Python defusedxml 替换标准库
.NET DtdProcessing=Prohibit XmlReaderSettings

XXE

几个容易踩的坑

下面这些是最常见的错误做法:

  • 只过滤 <!ENTITY:编码与参数实体可绕
  • 用一个解析器禁用、另一个没禁用
  • 认为只有 SOAP 才有 XML:Excel/Word 解析同样中招
  • 错误信息直接返回给前端

写在最后

XXE 的修复是最「配置化」的:打开一个开关就能根治,难的是把所有解析点都找全。

安全不是一次加固,是持续的假设:假设输入不可信、假设边界会破、假设有人会看错。

评论 (3)

半
半箱油

修复清单比漏洞描述有用多了,很多文章只讲怎么打不讲怎么防。

白
白帽小林

白名单那条永远是最有效的,正则黑名单迟早绕过。

运
运维老张

建议再补一条:把这类检查加到 CI 里,靠人记必然漏。

发表评论

验证码

提交后需站长审核,通过后才会显示。