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

Java中防止XXE(XML External Entity)攻击,核心是禁用外部实体解析和DTD处理。默认的XML解析器(如JAXP中的DocumentBuilder、SAXParser、Transformer)若未显式配置,可能启用外部实体,导致敏感文件读取、SSRF甚至远程代码执行。
禁用外部实体和DTD解析
对所有XML解析器实例,必须显式关闭http://apache.org/xml/features/disallow-doctype-decl和http://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_PROCESSING为true,并禁用http://javax.xml.XMLConstants/feature/secure-processing
使用白名单机制替代通用解析
如果业务必须处理带DOCTYPE的XML(极少见),不要开放全部实体,而是采用白名单方式预定义允许的实体,并重写EntityResolver:
- 实现
org.xml.sax.EntityResolver,对resolveEntity方法只返回已知安全的InputSource - 拒绝所有
systemId含file://、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”,而是“怎么确保它不会去碰不该碰的东西”。每种解析器都得单独配,不能只改一处就以为全安全了。










