xml注入攻击是攻击者通过恶意xml数据破坏结构或触发非预期行为,主要分三类:xml数据注入、xxe和xml炸弹;防御需同时验证与编码输入、禁用解析器危险功能,并优先选用json替代xml。

XML注入攻击是指攻击者通过向应用程序提交恶意构造的XML数据,破坏原有XML结构或触发解析器执行非预期行为,从而窃取数据、读取文件、执行命令甚至导致服务瘫痪。核心问题在于:把未经处理的用户输入直接拼入XML内容或作为XML解析参数使用。
关键风险类型要分清
不是所有XML相关漏洞都叫“XML注入”,但常被混用。实际需重点关注三类:
- XML数据注入:用户输入未转义就写入XML节点,比如把
张三<username>李四</username>塞进<username>...</username>,导致解析出多个节点,逻辑被篡改; - XXE(外部实体注入):XML中声明
,解析器加载后泄露敏感文件; - XML炸弹(Billion Laughs):利用嵌套实体无限展开,耗尽内存CPU,造成拒绝服务。
输入处理必须做两件事
只要用户数据要进XML,就得同时完成验证和编码,不能只做其一:
- 用白名单限制字符:用户名只允许中文、英文字母、数字、下划线,其余一律拒收或截断;
- 对保留字符做XML实体编码:
→<code><,>→>,&→&,"→",'→'; - 避免字符串拼接生成XML——改用dom、DocumentBuilder、dom4j等安全API构建节点,它们会自动处理文本内容转义。
解析器配置比代码更关键
很多漏洞根本不在业务逻辑里,而在XML解析器默认开启危险功能:
- Java中禁用DOCTYPE声明:
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - PHP中全局禁用外部实体:
libxml_disable_entity_loader(true),并在解析前调用libxml_use_internal_errors(true)屏蔽报错; - .NET中设置
XmlReaderSettings.DtdProcessing = DtdProcessing.Prohibit; - 所有场景下,除非绝对必要,否则关闭外部实体、参数实体、内联DTD解析。
能不用XML就别用
如果只是传简单数据,优先选JSON——它语法轻量、解析器普遍不支持实体扩展、现代语言SDK默认安全。若必须用XML,确保整个链路(接收、存储、解析、输出)都经过上述加固。框架如spring、ASP.NET虽有内置防护,但需手动开启对应开关,不能依赖默认配置。