Java如何防止XXE漏洞 Java XML解析安全设置

14次阅读

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

Java如何防止XXE漏洞 Java XML解析安全设置

Java中防止XXE(XML External Entity)漏洞的关键,是在解析XML时禁用外部实体和DTD处理。默认的JDK xml解析器(如DocumentBuilderSAXParsertransformerFactory等)在未显式配置防护时,可能加载远程或本地外部实体,导致敏感文件读取、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
text=ZqhQzanResources