Java怎么安全地处理外部实体 防止XXE

3次阅读

Java 防 XXE 攻击需禁用外部实体和 DTD 解析:对 DocumentBuilder、SAXParser、Transformer 等均须显式关闭相关特性;推荐 Jackson XML 或 DOM4J 并配合白名单 EntityResolver、输入校验与 WAF 防护。

Java 怎么安全地处理外部实体 防止 XXE

Java 中防止 XXE(XML External Entity)攻击,核心是禁用外部实体解析和 DTD 处理。默认的 XML 解析器(如 JAXP 中的 DocumentBuilder、SAXParser、Transformer)若未显式配置,可能启用外部实体,导致敏感文件读取、SSRF 甚至远程代码执行。

禁用外部实体和 DTD 解析

对所有 XML 解析器实例,必须显式关闭 http://apache.org/xml/features/disallow-doctype-declhttp://xml.org/sax/features/external-general-entities等关键特性:

  • DocumentBuilder:设置setFeature("http://apache.org/xml/features/disallow-doctype-decl", true),再设setFeature("http://xml.org/sax/features/external-general-entities", false)
  • SAXParser:在 SAXParserFactory 上调用setFeature(),同样禁用上述两项,以及http://xml.org/sax/features/external-parameter-entities
  • Transformer(用于 XSLT):通过 TransformerFactory 设置 FEATURE_SECURE_PROCESSINGtrue,并禁用http://javax.xml.XMLConstants/feature/secure-processing

使用白名单机制替代通用解析

如果业务必须处理带 DOCTYPE 的 XML(极少见),不要开放全部实体,而是采用白名单方式预定义允许的实体,并重写EntityResolver

  • 实现 org.xml.sax.EntityResolver,对resolveEntity 方法只返回已知安全的InputSource
  • 拒绝所有 systemIdfile://http://https://jar: 的请求
  • 避免调用 new InputSource(new FileInputStream(……)) 等直接加载路径的操作

优先选用现代、安全默认的库

避免依赖老版本 JDK 或未加固的第三方 XML工具

立即学习Java 免费学习笔记(深入)”;

  • JAXB(Unmarshaller)需配合 SecurityManager 或显式禁用外部实体;JDK 17+ 已弃用,建议迁移到 Jackson XML 或 DOM4J(配置后)
  • 推荐 Jackson XML(jackson-dataformat-xml):默认不解析 DTD,且可通过 XmlFactory 关闭XMLStreamConstants.FEATURE_DOCTYPE_DECLARATION
  • DOM4J 2.1.4+ 默认禁用外部实体,但仍建议调用 DocumentHelper.parseText(xml).setEntityResolver(null) 并校验输入

补充防御:输入验证与运行时限制

解析前加一层过滤,能显著降低风险:

  • 用正则或 XML Schema(XSD)预校验 XML 结构,拒绝含 /code>、 的输入
  • 在容器或 JVM 层启用SecurityManager(虽已废弃,但在受限环境仍可限制FilePermission
  • 生产环境部署 WAF 规则,拦截常见 XXE 载荷如]]>

基本上就这些。关键不是“怎么解析 XML”,而是“怎么确保它不会去碰不该碰的东西”。每种解析器都得单独配,不能只改一处就以为全安全了。

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-08发表,共计1611字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。