查看漏洞补丁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 | GET /static/%5c/%5c/../../1.txt HTTP/1.1 |