Java防XXE漏洞的关键是禁用外部实体和DTD处理:需对DocumentBuilderFactory、SAXParserFactory等显式关闭disallow-doctype-decl及两个external-*特性;优先用JSON替代XML,或选用默认安全的Jackson XML(≥2.9);辅以白名单校验、大小限制与JDK升级。

Java中防止XXE(XML External Entity)漏洞的关键,是在解析XML时禁用外部实体和DTD处理。默认的JDK XML解析器(如DocumentBuilder、SAXParser、TransformerFactory等)在未显式配置防护时,可能加载远程或本地外部实体,导致敏感文件读取、SSRF甚至RCE。
禁用DTD和外部实体(核心措施)
所有XML解析器都需显式关闭DTD解析和外部实体加载,不能依赖默认行为。不同API设置方式略有差异,但原则一致:
-
DocumentBuilderFactory:设
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)禁用DOCTYPE;再设setFeature("http://xml.org/sax/features/external-general-entities", false)和setFeature("http://xml.org/sax/features/external-parameter-entities", false) -
SAXParserFactory:同样调用
setFeature禁用上述三个特性,顺序无关,但必须全部关闭 -
TransformerFactory:对
newTransformer()生成的Transformer不直接生效;需确保输入源(如StreamSource)不包含恶意XML,更推荐在解析阶段(如先用DocumentBuilder安全加载)完成校验
使用安全的替代方案
若业务允许,优先避开通用XML解析:
- 用JSON替代XML传输数据,彻底规避XXE风险
- 如必须用XML,考虑使用
javax.xml.stream.XMLInputFactory(StAX),它默认不处理DTD,且可通过setProperty(XMLInputFactory.SUPPORT_DTD, false)进一步加固 - 第三方库如Jackson XML(
jackson-dataformat-xml)默认禁用XXE,但需确认版本≥2.9,并检查是否手动启用了XmlFactory.Feature.USE_DIRECT_METHODS等非安全选项
补充防御与验证手段
单靠禁用特性不够,还需结合其他实践:
立即学习“Java免费学习笔记(深入)”;
- 对用户提交的XML做白名单校验:仅允许必要标签、属性,用XSD或自定义规则过滤
- 限制XML大小(如
setLimit("entityExpansionLimit", 0)或流式读取时设缓冲区上限),防爆破式实体展开攻击 - 在沙箱环境或低权限JVM中解析不可信XML,避免文件读取后造成横向影响
- 升级JDK至8u191+或11.0.2+,新版已将部分解析器默认禁用外部实体(但仍建议代码层显式设置,不依赖JVM补丁)
常见错误配置示例
以下写法看似关闭了DTD,实则仍有风险:
- 只调用
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true),却漏掉两个external-*特性 → DTD被禁,但若XML含等参数实体,仍可能触发 - 用
SchemaFactory校验XML时,未关闭其内部DocumentBuilderFactory的外部实体 → 校验过程本身可能被利用 - Spring Framework项目中,
@RequestBody自动绑定XML时,仅配spring.jackson.xml.enabled=false,却未配置spring.http.converters.preferred-json-mapper=jackson,导致底层仍走不安全的SimpleXmlHttpMessageConverter










