XML注入攻击核心风险在于外部实体(XXE)、DOCTYPE滥用及未过滤用户输入拼接,防护需禁用外部实体、避免拼接输入、白名单验证、优先改用JSON。

XML注入攻击是指攻击者通过向应用程序提交恶意构造的XML数据,干扰或操控XML解析器行为,从而实现读取敏感文件、执行远程请求(SSRF)、触发拒绝服务(DoS),甚至执行任意代码等危害。它不单是“插入标签”那么简单,核心风险常来自外部实体(XXE)、DOCTYPE滥用、未过滤的用户输入拼接进XML结构等环节。
关键风险点在哪
常见触发场景包括:
- 用户输入直接拼接到XML字符串中再解析(如用
doc.createTextNode(input)未转义) - XML解析器默认开启外部实体加载,且未禁用DOCTYPE声明
- 后端接收XML请求(如SOAP、REST API中的application/xml)但未做输入净化
- 使用老旧或配置宽松的解析库(如libxml 2.9以前版本、未设安全特性的JAXP默认实例)
必须做的四件事
防护不是靠“加一层过滤”,而是从设计到解析全程设防:
-
禁用外部实体和DOCTYPE:这是防XXE的底线。Java中设置
disallow-doctype-decl、external-general-entities=false;PHP调用libxml_disable_entity_loader(true);Python lxml启用no_network=True -
绝不拼接用户输入进XML文本节点或属性值:改用DOM API的
createTextNode()或XMLWriter的WriteElementString()等安全方法,它们会自动转义、>、&等字符 - 输入验证走白名单而非黑名单:比如手机号只允许数字和+/-,邮箱用标准正则校验;避免“过滤掉”这类易绕过的黑名单策略
- 优先考虑换格式:如果不是强依赖XML(如遗留系统集成、SOAP服务),用JSON替代。它天然无实体、无DTD、解析器更轻量也更安全
开发时容易忽略的细节
有些坑看似小,却常导致防线失效:
- 框架虽内置防护(如Spring Boot 2.3+默认禁XXE),但若手动创建
DocumentBuilderFactory就可能绕过——必须显式配置安全特性 - 日志或调试代码里把原始XML打印出来,可能意外暴露
file:///etc/passwd这类读取结果 - 测试用例只覆盖正常XML,没测
]>这类恶意载荷&xxe; -
前端传来的XML已“看起来干净”,但后端二次解析时仍用不安全方式处理(比如用
eval()或innerHTML渲染)
基本上就这些。核心就三句话:别拼接、要禁外部实体、信不过的输入一律当毒药处理。安全不在功能多,而在每一步都守住边界。










