CVE-2026-47883 Spring Framework UrlHandlerFilter 重定向漏洞浅析
漏洞分析
Spring Framework 6.2 引入了 UrlHandlerFilter,特定情况下可能存在URL重定向漏洞。
0x00 CVE-2026-47883 =================== 在受影响版本中,当Spring应用启用 UrlHandlerFilter 的 redirect 模式且路径匹配模式非常宽泛时,Spring MVC 与 WebFlux 中 RedirectTrailingSlashHandler.handleInternal 会把请求 URI 去掉尾部斜杠后直接写入 Location 响应头。以双斜杠开头的请求路径会使 Location 成为协议相对地址,浏览器将用户跳转到外部站点,造成开放重定向风险。  **影响版本:** Spring Framework: - 7.0.0 - 7.0.8 - 6.2.0 - 6.2.19 `org.springframework.web.filter.UrlHandlerFilter` 与 WebFlux 的`org.springframework.web.filter.reactive.UrlHandlerFilter` 两个类均受到影响,涉及到的包为`spring-web`。 0x01 漏洞分析与复现 ============ 1.1 协议相对 URL ------------ 在实际分析前先了解一个点,参考https://www.rfc-editor.org/rfc/rfc3986#section-4.2 ,大致意思是如果HTTP 响应头 Location 如果值以两个斜杠`//`开头,就代表:协议继承当前网站,但跳转的目标主机域名由这个 Location 内容为准:  1.2 分析过程 -------- ### 1.2.1 UrlHandlerFilter Spring MVC 历史上默认开启 `useTrailingSlashMatch`,对于`@GetMapping("/foo")`的路由,会同时匹配 `/foo` 和 `/foo/`两种请求方式。 这种"宽容"实际上会带来一些安全问题,最常见的就是基于路径匹配的权限绕过。 Spring官方在最初的6.0版本弃用了后缀匹配模式,但是大型的存量应用里有大量Controller和第三方客户端 还一来着后缀匹配的逻辑,让每个企业自己实现一个 UrlRewriteFilter 成本太高。 **相关参考如下**: - <https://github.com/spring-projects/spring-framework/issues/28552> - <https://github.com/spring-projects/spring-framework/issues/31366> 于是Spring Framework 6.2 引入了 `UrlHandlerFilter`,从对应的文档也可以看到https://docs.spring.io/spring-framework/docs/6.2.19/javadoc-api/org/springframework/web/filter/UrlHandlerFilter.html ,该filter的优先级很高,会在 DispatcherHandler之前执行,然后按URL模型做统一的处理:  其中最常见的用法是对 **trailing-slash特性的兼容**:旧版本经常习惯在路径末尾多打一个 `/`,应用统一用 308(永久重定向)把请求规范化到无尾部斜杠的路径。 查看org.springframework.web.filter.UrlHandlerFilter的实现: 首先获取对应的请求路径后,会调用supports方法进行检查:  这里主要是检查请求路径是否以`/`结尾:  然后执行 `pattern.matches(path)`,这里就是匹配实际配置的生效路径,如果匹配,会进入 `RedirectTrailingSlashHandler.handleInternal`的逻辑,这里主要是调用trimTrailingSlash方法进行处理,然后设置loaction进行跳转:  一般情况下类似`/foo/`的请求经过处理后,会变成`/foo`然后永久重定向。 ### 1.2.2 漏洞成因 相关修复https://github.com/spring-projects/spring-framework/commit/30e3a5719e ,大致的修复逻辑是在trimTrailingSlash处理后,**仅当 location 以`//`开头且第三个字符不是`/`时,剔掉一个`/`**:  trimTrailingSlash方法逻辑也比较简单,主要是处理尾部额外的`/`:  那么结合前面的Location 如果值以两个斜杠`//`开头,浏览器在继承当前协议的同时,跳转的目标主机域名由这个 Location 内容为准的trick,就是具体利用的poc。 1.3 漏洞复现 -------- 基于前面的分析,相关的poc大致如下。`//` 是利用协议相对引用 (攻击载荷),尾部 / 则是满足supports进入对应的跳转逻辑,缺一不可: ```Java //<host>/ ``` 尝试搭建相关的环境进行复现,这里直接注册`UrlHandlerFilter.trailingSlashHandler("/**").redirect(HttpStatus.PERMANENT_REDIRECT).build()` ,对应漏洞通告里说的`全局去尾斜杠`常用配置,宽泛模式 `/**` 正是漏洞利用的前提: ```Java @Bean public UrlHandlerFilter trailingSlashRedirectFilter() { return UrlHandlerFilter.trailingSlashHandler("/**") .redirect(HttpStatus.PERMANENT_REDIRECT) .build(); } ``` 注册完后启动应用,正常情况下访问`/www.hack.com/`虽然Location写入了,但是实际浏览器仅仅只会认为是path,并不会跳转到hack.com:   使用poc进行测试,可以看到response里的Location 原样回显 `//www.hack.com` ,浏览器会把它当作协议相对 URL 跳转到外部站点,成功造成重定向风险:  更新版本后同样的poc没办法进行url跳转了,结合修复代码,也很好理解了: - `//evil.com` → `/evil.com`:刚刚的poc在处理后协议相对引用被破坏,会被判定成站内路径,浏览器只会跳回本站,攻击失效。 - `///path` → 保持不变:第三个字符仍是 `/`,浏览器把它当本地路径,不构成开放重定向。 0x02 修复方式 ========= - 升级到 **Spring Framework 6.2.20 / 7.0.9+** - 避免用 `/**` 这类宽泛模式配 redirect,尽可能把 trailing-slash 重定向收敛到真实业务路径前缀(如 `/api/**`),缩小命中范围 - 在反向代理 / 网关上规范化或直接拒绝以 `//` 开头的请求路径 (如 Nginx `merge_slashes on`) - 在网关 / Spring Security 自定义过滤器中对 `Location` 响应头做 出参检查,拒绝以 `//` 开头或指向非白名单主机的重定向
发表于 2026-09-29 09:00:02
阅读 ( 3608 )
分类:
代码审计
2 推荐
收藏
0 条评论
tkswifty
81 篇文章
×
温馨提示
您当前没有「奇安信攻防社区」的账号,注册后可获取更多的使用权限。
×
温馨提示
您当前没有「奇安信攻防社区」的账号,注册后可获取更多的使用权限。
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!