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

2022-06-09点击量:11661


前言

Spring Security 是 Spring 家族中的一个安全管理框架。在 Spring Security特定版本中存在一处身份认证绕过漏洞(CVE-2022-22978)。由于RegexRequestMatcher正则表达式配置权限的特性,当在Spring Security中使用RegexRequestMatcher且规则中包含带点号的正则表达式时,攻击者可以通过构造恶意数据包绕过身份认证。


影响版本

Spring Security 5.5.x < 5.5.7

Spring Security 5.6.x < 5.6.4


环境构建

目录结构

cc.saferoad.controller.Demo


cc.saferoad.config.SpringSecurityConfig

自定义配置类

cc.saferoad.cve202222978.Cve202222978Application

cc.saferoad.cve202222978.RegexRequestMatcherTests

单元测试类,用于后面具体分析流程代码

pom.xml

配置完成后,启动SpringBoot应用.访问http://localhost:8080

访问/admin/路由会提示403

或者使用笔者构建的环境 http://github.com/DeEpinGh0st/CVE-2022-22978


漏洞复现

正常访问/admin/下任何路由均会提示403

此时在/admin/anything路由中插入%0a或者%0d,即可绕过验证访问页面


漏洞分析

使用上文中的单元测试样例,首先进行RegexRequestMatcher实例化

根据构造参数初始化正则表达式及httpMethod属性,注意此处Pattern.compile参数值,对照JDK API文档看一下具体参数含义

其中第一个参数表示要编译的表达式,而第二个参数则是指定表达式的具体匹配模式,具体可选值有

CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS and COMMENTS

在RegexRequestMatcher中由于caseInsensitive设置为了false,所以此处的值为0 代表使用默认状态

随后进入RegexRequestMatcher:matches中在获取到传入的路由后进行路由匹配

此处我们需要注意一个点

在默认情况下正则表达式中的.是不会匹配\r\n换行符的,所以RegexRequestMatcher在进行正则匹配时不会处理\r\n从而可以绕过需要身份认证的页面


修复

在清楚具体绕过原理后,来看一下官方提交的修复措施

在5.6.4的diff中官方将DEFAULT默认匹配模式改为了Pattern.DOTALL点阵模式

在点阵模式下表达式会匹配\r\n等终止符,而在API文档中官方也进行了说明 默认情况下,此表达式与行终止符不匹配

而后也将Pattern.DOTALL在开启大小写区分的情况下进行了组合,这样无论是否开启大小写模式均使用点阵模式进行匹配


参考

JDK8 API

5.6.3...5.6.4 Diff

Regexp-syntax