
Spring Security フレームワークにおける CVE-2022-22978 脆弱性の PoC
調査した情報によると、これはSpring SecurityフレームワークのRegexRequestMatcherクラスに関連する脆弱性です。具体的には、正規表現にドット(.)が含まれているRegexRequestMatcherを使用するアプリケーションは、\r(%0a)、\n(%0d) という文字によってバイパスされる可能性があります。その結果、攻撃者は認証なしで許可されていないパスにアクセスできるようになります。
脆弱性の影響を受けるSpring Securityフレームワークのバージョン:
5.5.x から 5.5.7 未満5.6.x から 5.6.4 未満この脆弱性を静的に分析するために、Spring Securityのソースコードにアクセスする必要があります。具体的には、Github上で脆弱性のあるバージョン5.6.3と修正済みバージョン5.6.4のコミットを比較します。以下のリンクを参照してください:Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

RegexRequestMatcherクラスの変更を確認します。バージョン5.6.4では、デフォルトの.の代わりにPattern.DOTALLを使用していることがわかります。バージョン5.6.3ではデフォルトの.が使われていました。
ここで:
Pattern : java.util.regexパッケージに含まれる3つのクラスの1つで、正規表現を処理する機能を持ちます。Pattern.DOTALL : このフラグを使用すると、正規表現の“.”が\n、\rなどの改行文字を含むすべての文字にマッチします。Pattern.CASE_INSENSITIVE: 大文字小文字を区別しません。
デフォルトでは、正規表現の.は\n、\rなどの改行文字を除くすべての文字にマッチします。そのため、ある文字列のパターンを検証する正規表現関数がある場合、その文字列に改行文字が含まれていると正規表現はマッチしません。これを防ぐために、Pattern.DOTALLフラグを使用できます。
しかし、誰かが意図的に%0d(\nの代わり)や%0a(\rの代わり)を使用した場合、上記の正規表現は依然としてマッチしません。そのため、バージョン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」というテキストを出力するコントローラを作成します。

ステップ3: ユーザーが/admin/<any>パスにアクセスするたびに認証を要求するように設定します。具体的には、regexMatchers("/admin/.*").authenticated()を使用します。これが、攻撃者が悪用して/admin/<any>ページのコンテンツを認証なしで表示できるようにする脆弱性です。

ステップ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