
Spring Security の RegexRequestMatcher における CVE-2022-22978 認証バイパスのステップバイステップのデモ。脆弱なアプリのセットアップ、ペイロード実行、修正の検証を含みます。
調査した情報によると、これはSpring SecurityフレームワークのRegexRequestMatcherクラスに関連する脆弱性です。具体的には、正規表現にドット(.)を含むRegexRequestMatcherを使用するアプリケーションは、\r(%0a)、\n(%0d) などの文字によってバイパスされる可能性があり、攻撃者は認証なしで許可されていないパスにアクセスできてしまいます。
脆弱性の影響を受けるSpring Securityフレームワークのバージョン:
5.5.7 より前の 5.5.x5.6.4 より前の 5.6.xこの脆弱性を静的解析するために、Spring Securityのソースコードにアクセスする必要があります。具体的には、GitHubの2つのバージョン、5.6.3(脆弱性のあるバージョン)と5.6.4(修正済みバージョン)の間のコミット比較機能を使用します。次のリンクを参照してください: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

RegexRequestMatcherクラスの変更を確認します。バージョン5.6.4では、このクラスがバージョン5.6.3のようにデフォルトの.ではなくPattern.DOTALLを使用していることがわかります。
ここで:
Pattern : パッケージjava.util.regexに含まれる3つのクラスの1つで、正規表現を処理する機能を持ちます。Pattern.DOTALL : このフラグを使用すると、正規表現の「.」は\n、\rなどの改行文字を含むすべての文字にマッチします。Pattern.CASE_INSENSITIVE: 大文字と小文字を区別しません。
デフォルトでは、正規表現の.は\n、\rなどの改行文字を除くすべての文字にマッチします。そのため、ある文字列のパターンを検証する正規表現関数がある場合、その文字列に改行文字が含まれていると、その正規表現関数はマッチしません。これを防ぐには、Pattern.DOTALLフラグを使用できます。
しかし、誰かが\nの代わりに%0dを、\rの代わりに%0aを意図的に使用した場合、上記の正規表現は依然としてマッチしません。そのため、バージョン5.6.4では、RegexRequestMatcherTests.javaにこのケースをチェックする処理が追加されました。具体的には、%0dと%0aをそれぞれ\nと\rに変換してから正規表現でチェックします。

ステップ1: Spring Initializrを使用して、Spring SecurityとSpring Webの2つの依存関係を含むSpring Boot Webアプリケーションを作成します。

ステップ2: /admin/*パスへのリクエストがあったときにThis is a CVE-2022-22978 demoという文字を出力するControllerを作成します。

ステップ3: regexMatchers("/admin/.*").authenticated()を使用して、ユーザーが/admin/<任意>パスにアクセスするたびに認証メカニズムを設定します。これはまさに、攻撃者が認証なしで/admin/<任意>ページのコンテンツを閲覧するために悪用する脆弱性です。

ステップ4: 設定ファイルで、脆弱性を含むSpring Securityのバージョンを宣言します。ここではバージョン5.6.3を選択します。

ステップ5: gradlew bootRunコマンドでアプリケーションを実行します。プログラムはデフォルトでApache Tomcatを使用し、ポート8080で待ち受けます。/admin/xyzパスにアクセスします(/admin/で始まるパスであれば何でも構いません)。

結果として403 Forbiddenコードが返されます。これは、認証されていないためアクセスできないことを意味します。
このとき、Spring Security(バージョン5.6.3)のregexMatchers関数が\r(%0d)や\n(%0a)などの改行文字にマッチしないという脆弱性を利用すると、ペイロード/admin/%0dxyzを使用して認証なしで上記のパスにアクセスできます。

ペイロード/admin/%0axyzでも同様です。

このように、非常にシンプルなペイロードだけでCVE-2022-22978の脆弱性を悪用することに成功しました。
5.7.1を使用します
上記と同様のペイロード/admin/%0dxyzでWebを攻撃してみます。

このとき、アプリは攻撃者が期待するようなレスポンスを返しません。
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1