CVE-2024-38816

前言:

spring-webmvc存在CVE-2024-38816漏洞,首先看下其影响范围

可以看到5.3.0~5.3.39均受影响,且6版本的提供了升级,但是由于5.3.39已经过了生命周期,所以仅对付费的企业用户提供了升级版本,这就很尴尬了

下面看下具体的漏洞描述

翻译下来就是

通过功能web框架WebMvc提供静态资源的应用程序。fn或WebFlux。Fn容易受到路径遍历攻击。攻击者可以制作恶意HTTP请求并获取文件系统上的任何文件,这些文件也可以被运行Spring应用程序的进程访问。具体来说,当以下两种情况同时存在时,应用程序是易受攻击的:

  1. 这个web应用使用RouterFunctions来提供静态资源
  2. 资源处理是用FileSystemResource位置显式配置的

然而,当以下任何一种情况发生时,恶意请求将被阻止和拒绝:

  1. 已使用Spring安全HTTP防火墙
  2. 应用程序在Tomcat或Jetty上运行

这样写可能有点难以理解,下面我们分析下其具体漏洞原因

漏洞分析:

首先看下具体的调用RouterFunctions执行流程如下:

  1. 当调用 RouterFunctions.resources("/static/**", new FileSystemResource(...)) 时,实际上是在定义一个路由,告诉 Spring WebFlux 当收到匹配 /static/** 的请求时,应该如何处理。
  2. 当请求到达您的应用程序时,Spring WebFlux 会根据请求的 URL 路径查找匹配的路由。当请求的路径匹配 /static/** 时,PathResourceLookupFunction 会被触发。
  3. 在 PathResourceLookupFunction 中,以下步骤通常会执行:
    1. 路径解析:解析请求的路径,将其转换为一个文件系统路径。
    2. 资源查找:使用 FileSystemResource 对象查找实际的文件。此时,Spring 会检查给定的路径是否存在,并且可以读取。
    3. 资源响应:如果找到资源,apply 方法会创建一个 ServerResponse,设置适当的 HTTP 状态和响应头,比如 Content-Type 和 Content-Length,然后返回资源内容。
  4. 在成功找到资源并生成响应后,Spring WebFlux 会将 ServerResponse 发送回客户端。这意味着客户端可以接收到请求的静态文件,比如 CSS、JavaScript 或图片。

其实漏洞的原因非常简单,其代码位于PathResourceLookupFunction方法中

这里可以看到,首先使用如下代码获取到了请求的路径

request.requestPath().pathWithinApplication();

然后通过processPath函数获取到最终的path,然后使用 Resource 接口和 createRelative 方法用于处理资源的相对路径,其中this.location 是一个 Resource 对象,表示某个资源的基准位置。createRelative 方法用于在给定的基础资源位置上创建一个相对资源。这意味着它会根据 this.location 生成一个新的 Resource,其路径是基于 this.location 的相对路径。path 是一个字符串,表示要在 this.location 基础上创建的相对路径。这个字符串可以是一个相对路径。

漏洞测试:

测试前我们还需要了解什么是RouterFunction

RouterFunction 是 Spring WebFlux 中用于定义 HTTP 路由的核心组件。它的主要作用是将传入的 HTTP 请求映射到相应的处理程序。

其中resources方法可以触发本漏洞:

RouterFunctions.resources 是 Spring WebFlux 中用于处理静态资源请求的一个方便的方法。它允许您定义一个路由,以便能够提供静态文件(如 HTML、CSS、JavaScript 和图像等)给客户端。

做个简单的例子,当我们使用如下代码时

RouterFunctions.resources("/static/**", "classpath:/static/")

发送http://localhost:8080/static/styles.css时,就可以直接访问目录/static/styles.css,由此就产生了问题,如果没有对styles.css路径进行判断,就会产生漏洞,比如我发送../../../etc/passwd就会触发变成RouterFunctions.resources("/static/**", "/static/../../../etc/passwd"),进而读取到passwd信息输出,造成漏洞

下面我们编写代码测试

@Configuration
public class WebConfig {
    @Bean
    public RouterFunction<ServerResponse> route() {
        return RouterFunctions.resources("/static/**", new FileSystemResource("D:\\code\\cve-2024-38816\\static"));
    }
}

然后进行如下访问

http://127.0.0.1:8080/static/%2e%2e/pom.xml

然后我们就可以看到pom内容被输出到前端,如果时linux系统,可以使用

http://127.0.0.1:8080/static/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd

访问后就可以看到passwd内容被打印到前端

具体的漏洞成因很简单,但是要想成功利用,必须首先保证没有开启Spring安全HTTP防火墙并且应用程序在不在Tomcat或Jetty上运行

然后需要保证程序是使用RouterFunctions来提供静态资源且资源处理是用FileSystemResource位置显式配置的

上述两点缺一不可

漏洞修复:

漏洞修复可以看下6.1.13是如何修复的,地址如下:

https://github.com/spring-projects/spring-framework/commit/d86bf8b2056429edf5494456cffcb2b243331c49#diff-25869a3e3b3d4960cb59b02235d71d192fdc4e02ef81530dd6a660802d4f8707

对流程进行更多的校验和判断,具体可以自行查看:

主要通过isInvalidEncodedResourcePath方法进行了过滤,当包含../和..\的时候就会返回true,进而无法进入如下代码,进而进行了防御

Optional.of(resource);

注意:

修复的方案很简单,就是添加对../和..\的校验即可,但是这里有一个问题就是FileSystemResource里面的路径编写方式

new FileSystemResource("D:\\code\\cve-2024-38816\\static\\")
new FileSystemResource("D:\\code\\cve-2024-38816\\static")

这两种编写方式会出现很大的区别,如果使用第二种进行编写,则依旧可以使用../触发漏洞,该问题我提交到了官方,但是官方认为这个属于配置问题,不算漏洞

所以再编写代码的时候一定要注意路径最后要添加\\,否则依然可以利用../来实现目录的穿越进而读取文件 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值