Spring Framework路径遍历漏洞(CVE-2024-38816)

查看漏洞补丁https://github.com/spring-projects/spring-framework/commit/d86bf8b2056429edf5494456cffcb2b243331c49

可知问题出现在org.springframework.web.reactive.function.server.PathResourceLookupFunction中

PathResourceLookupFunction是Spring WebFlux中用于查找资源的函数,作用是将请求的路径映射到文件系统中的资源,如图片、样式表或 JavaScript 文件等,通常与RouterFunctions一起使用。

在org.springframework.web.reactive.function.server.PathResourceLookupFunction#apply中:

首先从请求ServerRequest中获取路径信息,并将其转换为PathContainer对象,检查路径是否与预定义的模式匹配,如果不匹配,则返回一个空的Mono对象

如果路径匹配,使用this.pattern.extractPathWithinPattern()从路径中提取与模式匹配的部分,并使用this.processPath()处理提取的路径部分。

如果路径包含特殊字符(如 %),则进行 URI 解码,并使用this.isInvalidPath()检查路径是否有效。

最后如果是有效的路径,尝试创建一个Resource对象。并返回对应的内容。

而在this.isInvalidPath中会调用StringUtils.cleanPath来判断

cleanPath的问题在于String[] pathArray = delimitedListToStringArray(pathToUse, “/“); 这个是允许空元素存在的,也就是说cleanPath会把//当成⼀个目录,而FileSystem是不会把//当成⼀个⽬录的。可参考CVE-2018-1271

因此可以使用///../ 通过 StringUtils.cleanPath(path).contains(“../“) 的检查。但是上⾯的this.pattern.extractPathWithinPattern会去掉路径中连续多个的/ 只保留⼀个/ ,所以写成//../../,到了StringUtils.cleanPath,\会再转换成/ 。

最后因为url中不能直接出现\ ,需要url编码写/%5c/%5c/../../

环境搭建

pom.xml中引入spring-boot-starter-webflux,默认使用Netty作为Web服务器

根据公告https://spring.io/security/cve-2024-38816,编写如下

补丁主要是在processPath中将\替换为/,在cleanDuplicateSlashes去掉了多余的/

在isInvalidEncodedInputPath,里面会先对path解码,然后调用processPath处理,最后经过isInvalidPath,使用双编码的方式同样无法通过检查。


1
2
3
4
GET /static/%5c/%5c/../../1.txt HTTP/1.1
Host: 127.0.0.1:8071
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.57 Safari/537.36
Connection: keep-alive