作者:spoock
作者博客:https://blog.spoock.com/2018/05/16/cve-2018-1259/
看pivotal发布的漏洞信息如下:
通过发布的漏洞信息可以知道,漏洞组件是在XMLBeam
1.4.14或者是更早的版本,主要原因是没有限制XML文件外部实体引用。而Spring Data Commons
的某些版本中使用了存在漏洞的XMLBeam
组件。
下载demo环境
git clone https://github.com/spring-projects/spring-data-examples.git cd spring-data-examples git checkout ad2b77e
使用IDEA打开其中的web/projection
项目,修改其中的pom.xml
文件:
修改spring-data-commons的版本
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>2.0.5.RELEASE</version> </dependency>
添加spring-boot的依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent>
漏洞组件版本如下:
注释example.users
中UserControllerClientTests.java
、UserControllerIntegrationTests.java
中的代码(主要是测试代码,对漏洞环境无影响)。
使用IDEA启动程序。采用POST方法发送XML的数据:
成功地读取了文件。
通过漏洞修复commit发现,对DefaultXMLFactoriesConfig.java
进行了修改,如下:
配置了默认的feature
禁止实体引用、禁止合并多个XML文档。关于XInclude的用法可以参考XML包含机制
通过补丁分析,漏洞原因是在于XMLBeam
漏洞版本中没有限制外部实体。
当我们发送Payload时,是由example.users.UserController
中的@PostMapping(value = "/")
来处理请求:
其中user.getFirstname()
已经完成了参数解析并读取c:/windows/win.ini
中的内容,所以我们发送的Payload在发送到Web应用之前已经由Spring Data Commons
对发送的参数进行了解析并绑定到user
对象上。而Spring Data Commons
是利用XMLBeam
解析XML文件,这样就导致了在Web应用响应请求时已经完成了XML的解析从而造成了XXE漏洞。
通过层层追踪,XML的解析最终是由org.xmlbeam.ProjectionInvocationHandler:invokeReadProjection()
处理,
XML的解析是由Node dataNode = (Node)expression.evaluate(node, XPathConstants.NODE);
完成,其中expression
就有xpath表达式,node
表示当前的document。最终解析完毕之后,data
返回的就是win.ini
的内容。
当我们更新XMLBeam
的版本至1.4.15时,即设置了instance.setXIncludeAware(this.isXIncludeAware);instance.setExpandEntityReferences(this.isExpandEntityReferences);
。分析invokeReadProjection()
函数
可以看到expression
中的xpath表达式保持不变,但是data
此时的结果已经为空,说明通过设置禁止实体引用就导致了XXE漏洞失效。
其实整个XML的解析与参数整个请求参数的传递并没有关系只和DefaultXMLFactoriesConfig
的配置有关,所以漏洞分析并不需要跟踪XML文件的解析过程,也不需要通过Spring Data Commons
去追踪数据流,只需要了解这个漏洞的本质原因即可。
这个XXE漏洞本质是因DefaultXMLFactoriesConfig.java
配置不当而导致的,Spring Data Commons
的某些版本中恰好使用了含有漏洞的XMLBeam
组件。这也就引出了一个问题,在Java这种大量使用第三方包的情况下,如何避免因第三方包的漏洞导致自己的应用也受到危害呢?