关于SAXParser未做安全配置所引发的安全漏洞分析
字数 1993 2025-08-07 08:22:31
Java XML解析安全配置与XXE漏洞分析
1. 概述
本文详细分析由于SAXParser未做安全配置所引发的XXE(XML External Entity)漏洞,通过两个实际案例(CVE-2022-0265和CVE-2022-0839)深入讲解漏洞原理、分析方法和修复方案。
2. XXE漏洞原理
XXE(XML External Entity Injection)漏洞发生在应用程序解析XML输入时,未正确配置XML解析器的安全选项,导致攻击者可以通过外部实体声明包含恶意内容。
2.1 常见危险场景
- 使用默认配置的SAXParser或SAXParserFactory
- 未禁用DOCTYPE声明
- 未启用安全处理模式
- 未限制外部实体引用
2.2 关键安全配置
// 禁用DOCTYPE声明
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// 启用安全处理
setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
// 禁用外部实体
setFeature("http://xml.org/sax/features/external-general-entities", false);
setFeature("http://xml.org/sax/features/external-parameter-entities", false);
3. CVE-2022-0265: Hazelcast XXE漏洞分析
3.1 漏洞描述
Hazelcast IMDG是美国Hazelcast公司的一套可扩展的开源数据分发平台。AbstractXmlConfigRootTagRecognizer()函数使用从没有设置FEATURE_SECURE_PROCESSING的SAXParserFactory生成的SAXParser,导致XXE攻击可能。
影响版本:Hazelcast < 5.1
3.2 漏洞代码分析
漏洞触发点在com.hazelcast.internal.config.AbstractXmlConfigRootTagRecognizer类中,直接调用JDK中默认的不安全方法:
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(new ByteArrayInputStream(xmlpoc.getBytes()), new HandlerBase());
3.3 漏洞调用栈分析
SAXParser.parse()方法执行恶意XXE语句- 进入
SAXParserImpl.parse方法 HandlerBase作为XML解析器处理恶意内容AbstractSAXParser.parse创建XMLInputSource对象XMLParser.parse检查fFeatures(安全配置缺失)XML11Configuration.parser开始XML解析XMLDocumentScannerImpl.startEntity完成解析
完整调用栈:
startEntity:529, XMLDocumentScannerImpl
startEntity:1327, XMLEntityManager
startEntity:1240, XMLEntityManager
scanEntityReference:1908, XMLDocumentFragmentScannerImpl
next:3061, XMLDocumentFragmentScannerImpl$FragmentContentDriver
next:602, XMLDocumentScannerImpl
scanDocument:505, XMLDocumentFragmentScannerImpl
parse:841, XML11Configuration
parse:770, XML11Configuration
parse:141, XMLParser
parse:1213, AbstractSAXParser
parse:643, SAXParserImpl$JAXPSAXParser
parse:342, SAXParserImpl
parse:139, SAXParser
main:14, cve_2022_0265
3.4 补丁分析
主要变更:
- 更换XML解析器
- 添加
FEATURES_DISALLOW_DOCTYPE安全配置 - 禁止使用DOCTYPE
修复后代码:
SAXParser saxParser = XmlUtil.getSAXParserFactory().newSAXParser();
saxParser.parse(new ByteArrayInputStream(xmlpoc.getBytes()), new HandlerBase());
4. CVE-2022-0839: Liquibase XXE漏洞分析
4.1 漏洞描述
Liquibase是用于跟踪、版本和部署数据库架构更改的工具。该漏洞源于XML外部实体引用限制不当。
影响版本:Liquibase < 4.8.0
4.2 漏洞代码分析
漏洞位于XMLChangeLogSAXParser类中,构造SAXParser解析器后未设置安全Feature:
XMLChangeLogSAXParser xmlChangeLogSAXParser = new XMLChangeLogSAXParser();
HashMap hashMap = new HashMap<String, String>();
hashMap.put("com/test/cve_2022_0839.xml", POC);
MockResourceAccessor resourceAccessor = new MockResourceAccessor(hashMap);
xmlChangeLogSAXParser.parse("com/test/cve_2022_0839.xml",
new ChangeLogParameters(), resourceAccessor);
4.3 漏洞调用栈分析
AbstractChangeLogParser.parse方法开始解析XMLChangeLogSAXParser.parseToNode实例化解析器- 检查features发现缺少安全配置
- 后续解析过程与前例类似
完整调用栈:
parse:777, XML11Configuration
parse:141, XMLParser
parse:1213, AbstractSAXParser
parse:649, SAXParserImpl$JAXPSAXParser
parseToNode:89, XMLChangeLogSAXParser
parse:15, AbstractChangeLogParser
main:30, cve_2022_0839
4.4 补丁分析
主要修复措施:
- 在
XMLChangeLogSAXParser.java中补充安全配置 - 添加
FEATURE_SECURE_PROCESSING - 设置其他相关安全属性
5. 安全开发建议
5.1 XML解析安全配置清单
SAXParserFactory spf = SAXParserFactory.newInstance();
// 关键安全配置
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// 其他推荐配置
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
spf.setXIncludeAware(false);
spf.setNamespaceAware(true);
SAXParser parser = spf.newSAXParser();
5.2 安全开发实践
- 始终验证XML输入:对用户提供的XML数据进行严格验证
- 使用白名单:只允许已知安全的XML结构和元素
- 限制实体解析:禁用或严格限制外部实体解析
- 使用最新库版本:确保使用的XML处理库是最新版本
- 安全配置检查清单:
- 禁用DOCTYPE
- 启用安全处理
- 禁用外部实体
- 禁用外部DTD
- 禁用XInclude
5.3 测试验证方法
- 使用以下XXE测试Payload验证防护措施:
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<test>&xxe;</test>
- 监控网络请求,确保没有对外部实体的请求
6. 总结
通过分析Hazelcast和Liquibase的XXE漏洞案例,我们可以得出以下结论:
- 默认配置不安全:Java XML解析器的默认配置通常不安全,必须显式配置安全选项
- 安全配置缺失是主因:两个案例都是由于缺少
disallow-doctype-decl和secure-processing等关键配置 - 修复方案明确:通过添加适当的安全Feature和Property可以有效防御XXE攻击
- 漏洞挖掘方向:检查所有XML解析点是否应用了安全配置是一个有效的漏洞挖掘方法
开发人员在使用XML解析功能时,必须充分了解相关安全风险,并实施适当的安全配置,以防止XXE等安全漏洞的发生。