01 解析层暗雷:XXE与不安全的反序列化


01 解析层暗雷:XXE 与不安全的反序列化

XML 外部实体 XXE 是应用开启了 XML 外部实体解析,让攻击者借解析器读取服务器本地文件、发起内部服务请求;不安全的反序列化则是应用对不可信数据做反序列化,攻击者通过构造特殊对象在反序列化时执行代码。两者都发生在“解析/还原数据”这一层,共同的续法是收紧解析器与数据来源。

第四幕开讲的是“替你做解析的代码”。多数开发以为“按官方文档调用解析库”就安全,其实解析器的默认行为未必安全。XXE 与反序列化是两个最有代表性的“解析层暗雷”,一个在医院、企业导入导出系统里高发,一个在注册克标语言生态里屡见报端。

一、XXE:外部实体让 XML 替你读文件

XML 允许在 DTD 里定义实体,而其中的外部实体能引用外部资源。若解析器开了外部实体且没限制,攻击者提交:

<?xml version="1.0"?> <!DOCTYPE x [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <root>&xxe;</root> ​

解析时 &xxe; 会被替换成 /etc/passwd 的文件内容,经页面回显或报错泄漏出来。进一步还能用 http:// 协议打内网服务。它在以下场景特别常见:上传或接收 XML 的接口、文档/配置文件导入导出、SOAP 风格接口。解析器默认允许外部实体,恰恰是漏的根源。

二、不安全的反序列化:还原对象时执行代码

把对象序列化成字节/字符串存起来、需要时再还原,是常见的缓存与状态手段。但若数据来自不可信来源,攻击者构造一个“还原后会触发危险动作”的特殊对象(如命令执行、文件写入),反序列化一瞬间就落地执行。语言生态里有经典反序列化链,前提往往只是“应用对不可信字节流调了还原函数”。难度越高,命中一次损失越大——可能直接拿操作系统权限。

这两个“解析层暗雷”各有各的触发开关,防御按钮也都明确。

二、不安全的反序列化:还原对象时执行代码

三、防御与加固要点

  • XXE:禁用 DTD/外部实体解析,用白名单限定实体类型;建议用 JSON 等更利于安全的格式替代 XML 接口;对必须解析 XML 的场景,明确关闭外部实体开关并校验文件类型。
  • 反序列化:优先使用自描述的、白名单类库的安全格式;对不可信数据一律不还原;若要接受对象流,确保来源可信且版本已修补已知链;加网络层与应用层双重隔离降低影响。
  • 两者共同原则:解析器/还原动作的默认设置要主动收紧,同时对输入来源分级——来自终端用户、无认证入口的数据,一律按“可能被构造”对待。

💡 关键直觉:看到“解析”“还原”“导入”“导出”四个词,就要自动联想到这两个漏洞。它们共用同一个信号:你的程序在“把一串陌生字节变成结构化东西”,而这一变形过程常比业务逻辑更容易出洞。

四、一次完整的演练

背景:一个接收 XML 且未关外部实体的演示接口。操作:提交含文件协议外部实体的 XML。结果:接口响应里回显了本地文件内容,XXE 成立。解读:解析器默认开启外部实体,实体引用被还原成文件内容。变式:在解析配置里关闭外部实体/禁用 DTD,重复提交同一 XML,实体不再被解析、接口拒绝而非回显,XXE 被封死。同样思路给数据流接入点换成白名单类还原,反序列化链也被切断。

五、XXE 与反序列化的对比,一眼记牢

两者常被并列,但触发位置和后果并不相同,可以放成一张对照。XXE 的问题是“解析 XML 时解析器太慷慨”,输错的是配置和 DTD 开关,危害以读文件、打内网为主,攻击者对 payload 形状有较多约束。反序列化的问题是“还原对象时信任了外来字节流”,输错的是数据来源和调用入口,危害往往直达代码执行、拿下更高权限。给一个记忆点:XXE 是“解析器把我的数据当成了它的功能”,反序列化是“还原器把我的对象当成了它的指令”。排查时看到 XML 就查外部实体开关,看到还原函数就查数据来源白名单,两条线索各走各的。

六、别把“只有一个入口”当成安心

这两种漏洞有个共同陷阱:团队常以为“这个接口是内部调用、外人碰不到”,于是在解析和还原上放松了把关。但内部接口也可能被上游其他漏洞带偏,或经 SSRF、越权、开放导出被间接触达。所以“输入是否可信”的判定不该看“调用方是谁”,而该看“这份数据能不能被外部间接改变”。只要存在让陌生字节变成结构化数据的路径,就要按可构造数据对待——这正是第一幕种下的“输入越界”结论在解析层的重演。

七、给解析层加“输入红绿灯”

与其全靠记性提醒“此处要关外部实体”,不如把解析层准入做成一道统一的闸门。凡是进系统的结构化数据,先过一个“红绿灯”判定:红灯直接拒绝——不可信来源、无认证入口带来的对象流/XML 一律不解析不还原,直接报“不支持的格式”;黄灯须把关——来源受限但可能被间接触达的数据,严格按白名单类库、关闭外部实体并做类型校验后再进;绿灯才放行——确认为内部可信且版本已修补的解析调用。把规则写进公共的解析封装,而不是散落在每个业务方法里各自决定,能保证“新接口默认就走安全解析”,而不是依赖某个开发记得关开关。这也是把第三幕“输入不信任度打分”的方法,落到了解析这个具体动作上。

本节要点回顾

  • XXE vs 反序列化:一个查外部实体开关、一个查数据来源白名单,两条线各走各的。
  • “内部调用”不是免责:只要数据可被外部间接改变,就按可构造数据把关解析与还原。
  • XXE 靠外部实体读取服务器文件、发起内网请求,根源是外部实体未关。
  • 不安全反序列化 靠构造特殊对象在还原时执行代码。
  • 解析器默认未必安全,外部实体解析往往需要主动关闭。
  • 输入来源分级,不可信数据一律按可构造对待,不还原、不解析外部实体。
  • 易出洞信号词:解析、还原、导入、导出、接收 XML。
作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U