Xalan包在XXE问题中的坑
字数 1156 2025-08-15 21:31:11

Xalan包在XXE防御中的问题分析与解决方案

一、问题背景

XXE(XML External Entity)攻击是一种常见的XML解析安全漏洞,攻击者通过构造恶意的XML文档,利用外部实体引用功能读取服务器上的敏感文件或发起SSRF攻击。

二、问题发现

在Java中使用TransformerFactory进行XML处理时,通常采用以下安全配置来防御XXE:

TransformerFactory factory = TransformerFactory.newInstance();
// 禁用DTD
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

但当业务代码引入了Xalan包(xalan:xalan:2.7.2)后,上述配置会抛出异常。

三、问题分析

3.1 Java SPI机制的影响

Java的SPI(Service Provider Interface)机制导致TransformerFactory的实现类被Xalan包替换:

  1. 未引入Xalan包时,默认实现类是JDK自带的:
    com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl

  2. 引入Xalan包后,实现类变为:
    org.apache.xalan.processor.TransformerFactoryImpl

这种变化是因为Xalan包在META-INF/services目录下定义了javax.xml.transform.TransformerFactory文件,指定了自己的实现类。

3.2 Xalan实现类的问题

Xalan的TransformerFactoryImpl存在以下问题:

  1. 不支持设置XMLConstants.ACCESS_EXTERNAL_DTDXMLConstants.ACCESS_EXTERNAL_STYLESHEET属性,设置时会抛出异常

  2. 虽然支持XMLConstants.FEATURE_SECURE_PROCESSING属性,但设置为true时不能有效阻止XXE漏洞

测试证明,即使设置了安全处理特性,Xalan仍然会解析外部实体:

<!DOCTYPE any [
<!ELEMENT any ANY>
<!ENTITY some SYSTEM "http://127.0.0.1:3344/nonexist">
]>
<any>&some;</any>

四、解决方案

4.1 指定使用JDK实现类

如果业务不需要Xalan的特殊功能,可以强制使用JDK自带的实现类:

TransformerFactory factory = TransformerFactory.newInstance(
    "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl",
    TransformerFactory.class.getClassLoader()
);
// 然后可以安全设置防XXE属性
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

4.2 其他注意事项

  1. Xalan包自2014年后未更新,存在已知安全问题
  2. Xalan设置不当还可能存在XSLT转换RCE漏洞
  3. 必须经过充分测试确认使用JDK实现类是否满足业务需求

五、最佳实践建议

  1. 尽量避免引入Xalan包,除非确实需要其特殊功能
  2. 如果必须使用Xalan,需要寻找其他方式防御XXE,如:
    • 前置XML过滤
    • 使用安全策略文件限制
  3. 定期检查XML处理相关的安全配置
  4. 新项目建议使用更现代的XML处理库

六、参考文档

  1. OWASP XXE防御指南
  2. Java SPI机制详解
  3. Xalan的XXE问题讨论
  4. Red Hat关于此问题的解决方案
Xalan包在XXE防御中的问题分析与解决方案 一、问题背景 XXE(XML External Entity)攻击是一种常见的XML解析安全漏洞,攻击者通过构造恶意的XML文档,利用外部实体引用功能读取服务器上的敏感文件或发起SSRF攻击。 二、问题发现 在Java中使用TransformerFactory进行XML处理时,通常采用以下安全配置来防御XXE: 但当业务代码引入了Xalan包(xalan:xalan:2.7.2)后,上述配置会抛出异常。 三、问题分析 3.1 Java SPI机制的影响 Java的SPI(Service Provider Interface)机制导致TransformerFactory的实现类被Xalan包替换: 未引入Xalan包时,默认实现类是JDK自带的: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl 引入Xalan包后,实现类变为: org.apache.xalan.processor.TransformerFactoryImpl 这种变化是因为Xalan包在 META-INF/services 目录下定义了 javax.xml.transform.TransformerFactory 文件,指定了自己的实现类。 3.2 Xalan实现类的问题 Xalan的TransformerFactoryImpl存在以下问题: 不支持设置 XMLConstants.ACCESS_EXTERNAL_DTD 和 XMLConstants.ACCESS_EXTERNAL_STYLESHEET 属性,设置时会抛出异常 虽然支持 XMLConstants.FEATURE_SECURE_PROCESSING 属性,但设置为true时 不能有效阻止XXE漏洞 测试证明,即使设置了安全处理特性,Xalan仍然会解析外部实体: 四、解决方案 4.1 指定使用JDK实现类 如果业务不需要Xalan的特殊功能,可以强制使用JDK自带的实现类: 4.2 其他注意事项 Xalan包自2014年后未更新,存在已知安全问题 Xalan设置不当还可能存在XSLT转换RCE漏洞 必须经过充分测试确认使用JDK实现类是否满足业务需求 五、最佳实践建议 尽量避免引入Xalan包,除非确实需要其特殊功能 如果必须使用Xalan,需要寻找其他方式防御XXE,如: 前置XML过滤 使用安全策略文件限制 定期检查XML处理相关的安全配置 新项目建议使用更现代的XML处理库 六、参考文档 OWASP XXE防御指南 Java SPI机制详解 Xalan的XXE问题讨论 Red Hat关于此问题的解决方案