CVE-2022-22978 Spring Security RegexRequestMatcher 认证绕过及转发流程分析
字数 1614 2025-08-27 12:33:37

Spring Security RegexRequestMatcher 认证绕过漏洞分析(CVE-2022-22978)

漏洞概述

CVE-2022-22978是Spring Security中RegexRequestMatcher组件的一个认证绕过漏洞,由于正则表达式处理特性导致某些需要认证的Servlet可能被绕过。影响版本包括:

  • 5.5.x prior to 5.5.7
  • 5.6.x prior to 5.6.4
  • Earlier unsupported versions

漏洞成因

漏洞核心在于正则表达式.默认不会匹配换行符,攻击者可以在URL中加入换行符(\r\n)来绕过正则表达式匹配。

补丁中新增了Pattern.DOTALL模式(0x20),该模式下表达式.会匹配任何字符包括行终止符。开发者也可以通过嵌入标志表达式(?s)启用Dotall模式。

环境搭建

使用Spring Boot 2.7.0和Spring Security 5.6.3版本进行测试:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
</parent>

<properties>
    <spring-security.version>5.6.3</spring-security.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

安全配置类示例:

@Configuration
public class SecurityDemo extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
            .regexMatchers("/admin/.*", "/admin2").authenticated();
    }
}

漏洞分析

关键调试点

  1. 正则匹配过程

    • 进入org.springframework.security.web.util.matcher.RegexRequestMatcher#matches方法
    • request.getServletPath()会对字符解码并删除;之后的字符到/字符
    • request.getRequestURI()会原样输出
  2. Spring Boot 2.7.0的请求处理流程

    • 从过滤器出来后,分发器(Dispatcher)选择相应处理器
    • org.springframework.web.servlet.DispatcherServlet#getHandler方法处理映射
    • RequestMappingInfoHandlerMapping继承AbstractHandlerMethodMapping
    • 虽然会移除分号,但在Spring Security前面就会被过滤
  3. Spring Boot 2.5.3的区别

    • lookupPath会将%0a解码,导致映射不到对应路由
    • 进入org.springframework.web.util.UrlPathHelper#decodeAndCleanUriString
    • decodeRequestString处将URL解码返回,导致路由映射失败

路由匹配机制

  1. 首先从directPath中寻找匹配
  2. 然后匹配带有通配符的path
  3. 最终匹配使用的是request对象
  4. org.springframework.util.AntPathMatcher#doMatch方法使用与RegexRequestMatcher相同的Pattern模式(flag为0),导致\n字符无法被匹配

绕过示例

基本绕过

在URL中加入换行符:

/admin/%0a

带参数的绕过

@RestController
public class NewController {
    @GetMapping("/admin2")
    public String noatuh(){
        return "hello admin2";
    }
}

参数拼接后与需要校验认证的路径进行对比时可能导致认证绕过。

修复方案

官方修复

升级到安全版本:

  • Spring Security 5.5.7+
  • Spring Security 5.6.4+

代码层面修复

在路径匹配中使用单行模式((?s)):

@Configuration
public class SecurityDemo extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
            .regexMatchers("/admin/(?s).*", "/admin2").authenticated();
    }
}

技术要点总结

  1. 正则表达式模式

    • 默认.不匹配换行符
    • Pattern.DOTALL(?s)启用单行模式
  2. 请求处理差异

    • 不同Spring Boot版本对URL解码处理不同
    • 高版本(2.7.0)能正确映射,低版本(2.5.3)会因解码导致404
  3. 安全防护

    • StrictHttpFirewall默认会过滤特殊字符
    • 但攻击者仍可能通过编码方式绕过
  4. 路由匹配优先级

    • 先匹配directPath
    • 再匹配通配符path
    • 最终使用request对象匹配

通过深入理解这些机制,可以更好地防御类似的安全漏洞。

Spring Security RegexRequestMatcher 认证绕过漏洞分析(CVE-2022-22978) 漏洞概述 CVE-2022-22978是Spring Security中RegexRequestMatcher组件的一个认证绕过漏洞,由于正则表达式处理特性导致某些需要认证的Servlet可能被绕过。影响版本包括: 5.5.x prior to 5.5.7 5.6.x prior to 5.6.4 Earlier unsupported versions 漏洞成因 漏洞核心在于正则表达式 . 默认不会匹配换行符,攻击者可以在URL中加入换行符( \r 或 \n )来绕过正则表达式匹配。 补丁中新增了 Pattern.DOTALL 模式(0x20),该模式下表达式 . 会匹配任何字符包括行终止符。开发者也可以通过嵌入标志表达式 (?s) 启用Dotall模式。 环境搭建 使用Spring Boot 2.7.0和Spring Security 5.6.3版本进行测试: 安全配置类示例: 漏洞分析 关键调试点 正则匹配过程 : 进入 org.springframework.security.web.util.matcher.RegexRequestMatcher#matches 方法 request.getServletPath() 会对字符解码并删除 ; 之后的字符到 / 字符 request.getRequestURI() 会原样输出 Spring Boot 2.7.0的请求处理流程 : 从过滤器出来后,分发器(Dispatcher)选择相应处理器 org.springframework.web.servlet.DispatcherServlet#getHandler 方法处理映射 RequestMappingInfoHandlerMapping 继承 AbstractHandlerMethodMapping 虽然会移除分号,但在Spring Security前面就会被过滤 Spring Boot 2.5.3的区别 : lookupPath 会将 %0a 解码,导致映射不到对应路由 进入 org.springframework.web.util.UrlPathHelper#decodeAndCleanUriString 在 decodeRequestString 处将URL解码返回,导致路由映射失败 路由匹配机制 首先从 directPath 中寻找匹配 然后匹配带有通配符的path 最终匹配使用的是 request 对象 org.springframework.util.AntPathMatcher#doMatch 方法使用与 RegexRequestMatcher 相同的Pattern模式(flag为0),导致 \n 字符无法被匹配 绕过示例 基本绕过 在URL中加入换行符: 带参数的绕过 参数拼接后与需要校验认证的路径进行对比时可能导致认证绕过。 修复方案 官方修复 升级到安全版本: Spring Security 5.5.7+ Spring Security 5.6.4+ 代码层面修复 在路径匹配中使用单行模式( (?s) ): 技术要点总结 正则表达式模式 : 默认 . 不匹配换行符 Pattern.DOTALL 或 (?s) 启用单行模式 请求处理差异 : 不同Spring Boot版本对URL解码处理不同 高版本(2.7.0)能正确映射,低版本(2.5.3)会因解码导致404 安全防护 : StrictHttpFirewall 默认会过滤特殊字符 但攻击者仍可能通过编码方式绕过 路由匹配优先级 : 先匹配 directPath 再匹配通配符path 最终使用 request 对象匹配 通过深入理解这些机制,可以更好地防御类似的安全漏洞。