Java中配置SAXParserFactory禁用外部实体需显式关闭disallow-doctype-decl、external-general-entities和external-parameter-entities等特性,JDK 7u45+/8u25+虽默认禁用但显式设置更可靠,旧版本需兼容处理并叠加预检与白名单防护。

Java中配置SAXParserFactory禁用外部实体,核心是关闭http://apache.org/xml/features/disallow-doctype-decl和http://xml.org/sax/features/external-general-entities等关键特性,防止XXE(XML External Entity)攻击。
设置关键安全特性为false
从JDK 7u45和JDK 8u25起,SAXParserFactory默认已禁用外部实体,但显式配置更可靠。需在创建解析器前调用setFeature()关闭以下特性:
-
http://apache.org/xml/features/disallow-doctype-decl:禁止DOCTYPE声明(最有效方式) -
http://xml.org/sax/features/external-general-entities:禁用外部通用实体 -
http://xml.org/sax/features/external-parameter-entities:禁用外部参数实体
完整安全初始化示例
推荐写法,包含异常处理与兼容性兜底:
SAXParserFactory factory = SAXParserFactory.newInstance();
// 禁用DOCTYPE声明(强制优先)
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// 显式关闭外部实体相关特性
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// 可选:禁用XInclude(如不使用)
factory.setFeature("http://apache.org/xml/features/xinclude", false);
SAXParser parser = factory.newSAXParser();
parser.parse(inputStream, handler);
注意JDK版本差异与兼容性
不同JDK版本对特性的支持略有差异:
立即学习“Java免费学习笔记(深入)”;
- JDK 7u45+ 和 JDK 8u25+:默认启用
disallow-doctype-decl,但建议仍显式设置 - 旧版本JDK(如6或早期7):可能不支持
disallow-doctype-decl,需依赖后两个特性组合,并确保使用最新Xerces或升级JDK - 若
setFeature抛ParserConfigurationException,说明该特性不被当前解析器支持,应跳过并加强其他防护(如预处理XML移除DOCTYPE)
补充防护建议
单靠SAXParserFactory配置不足以覆盖所有XXE场景,建议叠加以下措施:
- 输入XML前做简单预检:用正则或字符串匹配快速拦截含
/code>或外的SYSTEM/PUBLIC声明 - 使用白名单机制:仅允许特定元素和属性,结合
XMLFilter在解析时过滤可疑内容 - 生产环境统一使用更新的JDK(如11+或17+),其内置Xerces已强化XXE防御
