Xalan包在XXE问题中的坑

admin 2022年3月26日08:04:58评论107 views字数 3571阅读11分54秒阅读模式


Xalan包在XXE问题中的坑

一、问题发现


对于XXE问题,大家都不陌生。对于XXE的防御(修复)很多安全从业者也都知道 最安全的手段就是禁用DTD实体。文献【1】给出了各种语言下各类XML库的安全编码方式。在甲方环境下,笔者也曾参考此文档做了封装,供业务使用。读者可以思考这么做的好处与劣处(可以发散到其他场景)。


笔者封装的编码(修复)方案一直工作良好,直到有一天,业务反馈代码抛出了Exception,并且不是因为安全Block导致的Exception。幸运的是Exception在编码阶段就被发现了,没有将问题带到线上。

以下是抛出Exception的代码片段:


public static void main(String[] args) throws IOException, TransformerException {
TransformerFactory factory = TransformerFactory.newInstance(); //禁用DTD(导致报错的代码) factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");    factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);    //System.out.println(factory.getClass()); InputStream is = new FileInputStream("test/java/a.txt"); StreamSource ss = new StreamSource(is); Transformer transformer = factory.newTransformer();
transformer.transform(ss, new DOMResult()); is.close();}

二、问题分析

2.1 问题复现

拿到给的代码片,运行了一下。发现并没有出现Exception,并且,上述代码片在写SDK就测试过,并没有异常抛出,也符合文献【1】给的修复建议。于是再次和RD确认,对factory的实例类打印处理,发现RD使用了xalan包mvn坐标如下:


写SDK时的测试代码

@RequestMapping("/xxe7")@ResponseBodypublic String testTransformerFactory(@RequestBody String xml) throws TransformerException {    TransformerFactory tf = TransformerFactory.newInstance();
XmlDtdSafeguard.disableDtd(tf); //禁用DTD
StreamSource source = new StreamSource(new StringInputStream(xml)); tf.newTransformer().transform(source, new DOMResult()); return "testTransformerFactory";}
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<!--最新的包-->
<version>2.7.2</version>
</dependency>

通过运行测试,发现:

当添加了上述jar包是,TransformerFactory的实现类是org.apache.xalan.processor.TransformerFactoryImpl,并且设置禁用DTD属性时报错。当不添加上述依赖,TransformerFactory的实现类是com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl设置禁用DTD时不会报错。

2.2 JAVA SPI机制导致接口实现类被jar默认修改

从2.1的测试结果来看,添加一个jar包,就修改了接口的实现类。这必然需要JDK提供一定的扩展机制。处于自己太菜鸡,只是知道必然是有扩展机制,但是尚不知道是什么扩展机制导致。于是,两个方向来确定是什么扩展机制。


万能的搜索引擎:TransformerFactoryImpl,XXE,JDK,ServiceLoader mechanism(后来才知道)

观察jar包特征:jar包下/META-INF/services的正好定义了TransformerFactory接口文件

于是,发现TransformerFactory接口的实现类被修改是因为Java SPI的原因,参考【2】。我们也从源码层面看下:


Xalan包在XXE问题中的坑


可以看到,获取TransformerFactory接口实现类时:

首先从${java_home}/lib/jaxp.properties文件来确定实现类;

如果没有定义,则通过SPI机制来确定;

如果上述都没有,则使用硬编码的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl作为实现类。


Xalan包在XXE问题中的坑


Xalan包在XXE问题中的坑


在xalan包下确实定义了TransformerFactory实现类:


Xalan包在XXE问题中的坑


2.3 xalan TransformerFactoryImpl的报错原因及安全性

2.3.1 报错原因定位


2.2就解释了为什么加了xalan包,TransformerFactory的就发生了改变。这里还有个问题,为什么xalan的TransformerFactoryImpl类设置禁用DTD时会报错?

我们直接看xalan的TransformerFactoryImpl类的setFeature()和setAttribute()代码可以看到这个类根本不支持XMLConstants.ACCESS_EXTERNAL_DTD 和XMLConstants.ACCESS_EXTERNAL_STYLESHEET属性,并抛出异常。


Xalan包在XXE问题中的坑


Xalan包在XXE问题中的坑


看下JDK的实现类com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl,是支持这两个属性的,所以我们在测试时没有报错。


Xalan包在XXE问题中的坑


综上,我们定位到了业务报错的原因。其实这个问题,老外还几年前就提出来了 但是Xalan官方并没有解决(xalan在2014年之后再没有发版)参考【3】【4】【5】【6】。


2.3.2 安全性分析


既然,Xalan不支持设置上述属性,想必也是不安全的。我们猜测下证明我们的想法。注意我们看到xalan支持另一个属性XMLConstants.FEATURE_SECURE_PROCESSING,我们将这个属性设置为true,进行测试,发现其不能有效阻止XXE漏洞


<!--测试payload-->
<!DOCTYPE any [
<!ELEMENT any ANY>
<!ENTITY some SYSTEM "http://127.0.0.1:3344/nonexist">
]>

<any>&some;</any>

三、问题解决

看了下xalan的相关源码,发现没有好的方式可以禁用DTD(常规加固思路代价有点大)。其实,很多RD在使用xalan时,并不知道其使用了SPI机制。这也就说明,RD在做xml解析时,可能没有使用xalan对比jdk的额外属性(笔者在一天内解决此问题)。于是和RD确认了下,使用JDK自带的实现的能满足要求(一定要经过测试)。并且,TransformerFactoryImpl提供了不使用,使用指定实现类的方法,遂解决。


TransformerFactory factory = TransformerFactory.newInstance(TransformerFactoryImpl.class.getName(),TransformerFactoryImpl.class.getClassLoader());
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

写在最后,以上仅是短期帮助业务快速定位和解决问题,此库是否有其他属性能够支持安全处理XML尚待研究。此外,此库设置不当还存在XSLT转换RCE漏洞,本文不多做介绍。笔者水平有限,欢迎指正。


Xalan包在XXE问题中的坑


本文始发于微信公众号(疯猫网络):Xalan包在XXE问题中的坑

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月26日08:04:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Xalan包在XXE问题中的坑http://cn-sec.com/archives/505759.html

发表评论

匿名网友 填写信息