Spring Security 是 Spring 家族中的一個安全管理框架。在 Spring Security特定版本中存在一處身份認證繞過漏洞(CVE-2022-22978)。由于RegexRequestMatcher正則表達式配置權(quán)限的特性,當(dāng)在Spring Security中使用RegexRequestMatcher且規(guī)則中包含帶點號的正則表達式時,攻擊者可以通過構(gòu)造惡意數(shù)據(jù)包繞過身份認證。
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應(yīng)用.訪問http://localhost:8080
訪問/admin/路由會提示403
或者使用筆者構(gòu)建的環(huán)境 https://github.com/DeEpinGh0st/CVE-2022-22978
正常訪問/admin/下任何路由均會提示403
此時在/admin/anything路由中插入%0a或者%0d,即可繞過驗證訪問頁面
使用上文中的單元測試樣例,首先進行RegexRequestMatcher實例化
根據(jù)構(gòu)造參數(shù)初始化正則表達式及httpMethod屬性,注意此處Pattern.compile參數(shù)值,對照JDK API文檔看一下具體參數(shù)含義
其中第一個參數(shù)表示要編譯的表達式,而第二個參數(shù)則是指定表達式的具體匹配模式,具體可選值有
CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS and COMMENTS
在RegexRequestMatcher中由于caseInsensitive設(shè)置為了false,所以此處的值為0 代表使用默認狀態(tài)
隨后進入RegexRequestMatcher:matches中在獲取到傳入的路由后進行路由匹配
此處我們需要注意一個點
在默認情況下正則表達式中的.是不會匹配\r\n換行符的,所以RegexRequestMatcher在進行正則匹配時不會處理\r\n從而可以繞過需要身份認證的頁面
在清楚具體繞過原理后,來看一下官方提交的修復(fù)措施
在5.6.4的diff中官方將DEFAULT默認匹配模式改為了Pattern.DOTALL點陣模式
在點陣模式下表達式會匹配\r\n等終止符,而在API文檔中官方也進行了說明 默認情況下,此表達式與行終止符不匹配
而后也將Pattern.DOTALL在開啟大小寫區(qū)分的情況下進行了組合,這樣無論是否開啟大小寫模式均使用點陣模式進行匹配