2024年10月25日,Spring官方发布了一个关键安全漏洞CVE-2024-38821。在特定条件下,攻击者可以借此访问受限资源。
这个漏洞specifically涉及Spring WebFlux的静态资源服务功能。要使应用程序受到影响,需要同时满足以下所有条件:
使用WebFlux框架
启用了Spring的静态资源支持
对静态资源配置了非permitAll的授权规则
本文将深入分析这个漏洞的细节,并解释为什么它只影响静态资源。
漏洞利用样例代码可以在这里找到:https://github.com/mouadk/cve-2024-38821/tree/main
漏洞详解
接下来我们深入了解这个漏洞的具体细节和背景知识。
如果您不想阅读大段文字,这里有一张图展示了漏洞的攻击流程。
WebFilterChainProxy类解析
Spring Security的核心功能主要通过安全过滤器来实现。当我们配置多个安全过滤器时,为了便于管理,会有一个过滤器链位于顶层,负责将请求转发给下游过滤器。
DefaultWebFilterChain是WebFilterChain接口的默认实现。WebFilterChainProxy是一个用于委派给多个SecurityWebFilterChain实例的过滤器。
WebFilterChainProxy详解
我们的应用中可以配置多个安全过滤器。只有当所有过滤器都通过请求时,该请求才能继续在应用中传递。
DispatcherHandler类解析
DispatcherHandler
在WebFlux中的作用类似于Spring MVC中的DispatcherServlet
,负责处理HTTP请求。在初始化阶段,它会发现特定的Bean,根据接收到的请求将任务委派给这些Bean。具体的处理逻辑实现在DispatcherHandler的handle方法中。
主要流程如下:
-
遍历所有映射来查找合适的处理器,遵循"先到先得"原则。如果找不到处理器就抛出异常。 -
然后,尝试找到支持当前处理器的HandlerAdapter。如果找不到则返回错误。
给定一个HTTP请求(封装在ServerWebExchange中),getHandler负责为这个请求解析出合适的处理器。
AbstractHandlerMapping
当请求到达时,只有在通过安全过滤器后才会调用DispatcherHandler
。如果安全过滤器链允许或未能拒绝请求,DispatcherHandler
就会识别合适的处理器(通过依次评估潜在匹配项并选择第一个成功的)。
攻击者可以通过构造特殊的URL路径来绕过安全过滤器,避开对受保护资源的检查。例如,如果要保护/index.html
,攻击者可以将URL改为//index.html
。由于安全过滤器执行严格的路径匹配,这种情况下就不会触发检查,可能导致资源失去保护。如果所有安全过滤器都被绕过,就可能导致未经授权的访问。
通过安全过滤器后,特定的处理器会处理请求。Spring默认添加了一个特殊的处理器ResourceWebHandler
(实现了HttpRequestHandler
接口),用于从ResourceHandlerRegistry定义的特定位置提供静态资源,如图片、HTML和YAML文件等。这些位置包括:
-
public/
-
static/
-
resources/
-
META-INF/resources/
举例来说,使用路径..//index.html
时,请求的路径会通过exchange.getRequiredAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)
解析,结果为index.html
。攻击者可以利用这个机制进行攻击。
ResourceWebHandler
为什么非静态资源不受影响
非静态资源的处理方式不同。这些路由的处理器即使在所有安全过滤器被绕过的情况下,也会使用谓词来验证请求。例如,PathPatternPredicate
会严格匹配路径,对于不符合匹配规则的请求会返回HTTP 400 NOT FOUND,而不是错误地授予访问权限。
RequestPredicates
攻击流程
攻击者的请求在应用中的传递路径如下:DispatcherHandler -> SimpleHandlerAdapter -> ResourceWebHandler -> PathResourceResolver -> Resource -> Attacker Access
这个漏洞由[email protected]负责任地报告。
漏洞演示
漏洞利用样例代码可以在这里找到:https://github.com/mouadk/cve-2024-38821/tree/main
让我们配置以下设置来保护特定路径,包括/secure/hello
、/index.html
和/application.yaml
:
接下来配置如下路由:
我们可以确认这个配置对于正常请求是有效的。
然而,只要稍作修改,比如添加一个反斜杠(/
),攻击者就能绕过过滤器并访问静态资源。
相比之下,使用这种方法访问动态资源(如/secure/hello
)会得到"NOT FOUND"错误,这正如前面所解释的。
修复方案
修复提交
解决方案主要是加强了请求验证。具体来说,在安全链中引入了一个防火墙来验证请求,确保请求在到达过滤器链之前就经过验证。你可以在上面的GitHub提交中查看具体修改:GitHub提交记录。这次更新引入了ServerWebExchangeFirewall
(具体是StrictServerWebExchangeFirewall
)并增加了额外的验证方法。
强烈建议升级你的Spring依赖,并在今后采用"默认拒绝"的安全策略。此外,建议使用声明式安全配置,这种方式更难被攻击者绕过,因为他们常常会尝试操纵安全过滤器链。
如果我们用修复版本重试之前的攻击请求,会收到"Bad Request"错误:
这个案例也表明,虽然RASP可能会有帮助,但不一定能发现这类漏洞。至于ADR的效果,则要视具体情况而定。
对攻击者要保持警惕,采取严格的安全措施
原文始发于微信公众号(独眼情报):【PoC】Spring框架爆出严重漏洞CVE-2024-38821详解
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论