什么是 Spring WebFlux?
Spring框架是一个广泛使用的基于Java的应用程序框架,为企业级Java应用的开发提供基础设施支持。
Spring Security是一个功能强大的身份验证和访问控制框架,也是保护基于 Spring 的应用程序的行业标准。它提供身份验证和授权,并且可以轻松扩展以满足自定义要求。
Spring WebFlux是在 Spring 5 中引入的,作为传统Spring Web MVC框架的响应式编程替代方案。
Spring WebFlux 的核心设计旨在处理异步、非阻塞和反应式编程范例。它提供了一种反应式编程模型,允许开发人员构建可扩展、响应迅速且具有弹性的应用程序。WebFlux 不使用传统的每个请求一个线程的方法,而是利用反应式流 API,该 API 允许使用少量线程同时处理多个请求。
漏洞背景
2023 年 7 月 18 日,Spring Security 发布了包含此安全公告的新版本,这引起了我们的注意,因为这是一个过滤器绕过漏洞。搜索 Spring 的 GitHub 存储库,这是修复提交。
漏洞详细信息
Spring 公告中的描述非常抽象,并没有详细说明哪些 Spring 用例受到该问题的影响。
以下是我们对源代码的深入分析,从修复提交 - 7813a9b 开始。
文件中的变化web/src/main/java/org/springframework/security/web/server/util/matcher/PathPatternParserServerWebExchangeMatcher.java
看起来很有趣:
当并排查看差异时,在修复之前,我们可以看到该类PathPatternParserServerWebExchangeMatcher
使用了parse()
该类中实现的方法PathPatternParser
。
修复提交引入了一个新parse()
功能,在PathPatternParserServerWebExchangeMatcher
类本身中实现,它扩展了withparse()
的方法。PathPatternParser``initFullPathPattern()
查看源代码,我们可以看到,实用函数仅在字符串开头不存在正斜杠时才添加该斜杠。
/**
* Prepare the given pattern for use in matching to full URL paths.
* By default, prepend a leading slash if needed for non-empty patterns.
* @param pattern the pattern to initialize
* @return the updated pattern
* @since 5.2.25
*/
public String initFullPathPattern(String pattern) {
return (StringUtils.hasLength(pattern) && !pattern.startsWith("/") ? "/" + pattern : pattern);
}
当呈现新引入的测试时,进一步查看提交可以证实这一评估:
class PathPatternParserServerWebExchangeMatcherTests {
@Test
void matchesWhenConfiguredWithNoTrailingSlashAndPathContainsSlashThenMatches() {
PathPatternParserServerWebExchangeMatcher matcher = new PathPatternParserServerWebExchangeMatcher("user/**");
MockServerHttpRequest request = MockServerHttpRequest.get("/user/test").build();
assertThat(matcher.matches(MockServerWebExchange.from(request)).block().isMatch()).isTrue();
}
}
测试为路径创建一个解析器user/**
并检查它是否与路径匹配/user/test
。如果在此提交中不添加前斜杠,路径将不会匹配。initFullPathPattern()
确保它们确实匹配。
所有这些和**
路径有什么关系?
以下自定义过滤器包含**
。假设您想让网站上除管理页面之外的所有页面均可访问,则可能设置了以下规则:
.authorizeExchange()
.pathMatchers("admin/**")
.hasRole(Roles.ADMIN)
.and()
.authorizeExchange()
.anyExchange()
.permitAll();
(明智地)认为现在下面的每个页面admin/
只有管理员才能访问。
修复之前,此规则不会匹配任何admin/
URL,因为它缺少前面的 /,并且其下的所有网页admin/
都可以被任何人访问。
概念验证
我们创建了一个简单的 Spring WebFlux 应用程序,其中包括用户和管理员角色,并使用了存在漏洞的 Spring Security 版本。
在此应用程序中,有一个登录页面和一个管理端点。
规则如下:
http
// disable CSRF
.csrf().disable()
// add AuthenticationWebFilter and set the handler
.formLogin()
.authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler())
.authenticationFailureHandler(((webFilterExchange, exception) -> Mono.error(exception)))
.and()
.authorizeExchange()
.pathMatchers("admin/**")
.hasRole(Roles.ADMIN)
.and()
.authorizeExchange()
.anyExchange()
.permitAll();
return http.build();
.anyExchange().permitAll()
允许访问所有页面,但管理页面除外,如 所指示的.pathMatchers(“admin/**”).hasRole(Roles.ADMIN)
。
由于存在漏洞,该“admin/**”
规则无法匹配任何 URL,因为它开头缺少一个斜杠。例如,攻击者无需实际成为管理员****即可自由访问该 URL“/admin/supershell”
。我们的 PoC 显示了这些页面如何仍可访问。
如果攻击者知道以这种易受攻击的方式“保护”的端点,则可以轻松访问特权端点而无需任何身份验证。
谁会受到 CVE-2023-34034 的影响
此漏洞在以下条件下存在:
-
Web 应用程序使用 Spring WebFlux 框架(使用较旧的“Spring MVC”框架的应用程序不受影响)。 -
该 Web 应用程序使用了存在漏洞的 Spring Security 版本。例如,5.6.0。 -
Web 应用程序使用 URL 路径过滤来设置 Spring Security 访问规则。URL 路径模式不以正斜杠字符 ( /
) 开头。例如,pathMatchers("admin/supershell")
。这将影响单个页面,在本例中为admin/supershell
页面。 此外,如果 URL 路径包含多段通配符 (**
),则会增加漏洞的严重性。例如,pathMatchers("admin/**")
。这将影响 URL 路径下的所有页面,在本例中为admin
页面下的所有内容。
补救措施
强烈建议将 Spring Security 版本升级到以下版本之一:
-
6.1.2+ -
6.0.5+ -
5.8.5+ -
5.7.10+ -
5.6.12+
以上需要 Spring Framework 版本:
-
6.0.11+ -
5.3.29+ -
5.2.25+
或者,在 Spring Security 中使用的任何 URL 过滤器中添加前导斜杠 /。
例如,替换 –
pathMatchers("admin/**")
和 -
pathMatchers("/admin/**")
原文始发于微信公众号(红云谈安全):Spring WebFlux – CVE-2023-34034 – 撰写和概念验证
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论