禁用dtd与外部实体解析是防御xxe最核心措施。无论dom、sax或stax解析器,均须显式关闭相关特性:dom需设disallow-doctype-decl和external-general-entities为true/false;sax需禁用external-general/parameter-entities;stax需setproperty(support_dtd, false)及is_supporting_external_entities为false。

Java中处理XML时若未禁用外部实体(XXE),攻击者可利用恶意DTD注入读取本地文件、发起内网探测甚至执行远程请求。当启用安全防护后抛出 XmlSecurityException,说明防护机制已生效,但需确认是否配置正确、拦截是否覆盖全部XML解析路径。
禁用DTD与外部实体解析
这是防御XXE最核心的措施。无论使用DOM、SAX还是StAX解析器,都必须显式关闭外部实体加载能力。
-
DOM解析器:设置
DocumentBuilderFactory的两个关键属性为false:http://apache.org/xml/features/disallow-doctype-decl和http://xml.org/sax/features/external-general-entities -
SAXParserFactory:同样禁用
http://xml.org/sax/features/external-general-entities和http://xml.org/sax/features/external-parameter-entities -
StAX(XMLInputFactory):调用
setProperty(XMLInputFactory.SUPPORT_DTD, false),并设置IS_SUPPORTING_EXTERNAL_ENTITIES为false
使用白名单机制替代通用XML解析
对业务场景明确的XML输入,优先采用JAXB或Jackson XML等框架,并配合Schema校验或注解约束字段范围。避免直接用原始解析器处理不可信来源的XML。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- JAXB可结合
@XmlRootElement和@XmlElement限定结构,配合SchemaFactory做XSD验证 - Jackson XML默认不支持DTD,但仍建议显式禁用:通过
XmlMapper设置configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)增强健壮性
统一拦截入口与异常处理
若应用中存在多个XML解析点,应在统一网关层或工具类中封装安全的解析方法,避免重复配置遗漏。遇到XmlSecurityException时,不应简单吞掉异常,而应记录日志并返回标准化错误响应。
- 自定义异常处理器捕获
XmlSecurityException、SAXParseException等,区分是恶意输入还是格式错误 - 在Spring MVC中可通过
@ControllerAdvice全局处理,返回HTTP 400或422状态码 - 日志中记录原始XML片段(脱敏后)及请求上下文,便于溯源分析
依赖库版本与扫描加固
部分老版本XML解析库(如早期Xerces、Woodstox)存在绕过防护的漏洞。确保使用主流库的最新稳定版,并定期用OWASP Dependency-Check等工具扫描已知CVE。
- 推荐使用JDK自带解析器(1.7+已默认加强),避免引入非必要第三方XML库
- 若使用Apache Santuario等安全库,确认其
XMLUtils等工具类已开启secureProcessing模式 - CI/CD流程中加入静态扫描(如SonarQube规则S2755)识别潜在XXE风险代码
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










