著者: Sean Pesce
このプロジェクトは、Java Spring Framework における URL パースの脆弱性 CVE-2024-22243 の悪用可能なシナリオを示すサンプル Web アプリケーションを含んでいます(公式開示はこちら)。
影響を受けるバージョンの Spring は、URL の "userinfo" セグメント を独自の方法でパースし、その結果、他の多くの一般的なライブラリとは異なるホスト名セグメントを抽出する可能性があります。
異常な動作は、UriComponentsBuilder クラス内の以下の正規表現("regex")に起因します(2014年のこのコミットで導入されました)。
private static final String USERINFO_PATTERN = "([^@\\[/?#]*)";
この正規表現は、userinfo セグメント内の「左括弧」文字([)を許可しません。しかし、Spring はこの動作において例外的であるように見えるため、UriComponentsBuilder.fromUriString または を使用して構築された オブジェクトに対して を呼び出すと、予期しない動作が発生する可能性があります。、、 クラスも、内部で を使用しているため影響を受けます。したがって、 を直接使用しなくても、実装が脆弱になる可能性があります。
getHost()UriComponentsBuilderUriComponentsBuilder特別に細工された入力に対して、Spring は以下のすべてとは異なるホスト名の値を返します。
java.net.URI(特定の Java バージョンのみで報告されています。他のバージョンでは URISyntaxException が発生します)java.net.URLcurlandroid.net.Uriokhttp3.HttpUrlurllib.parse.urlparse(このリストは網羅的ではないことに注意してください。)
この動作により、依存する実装が認可やその他セキュリティ関連のメカニズムに信頼できるホスト名を使用している場合、Spring ベースの Web アプリケーションが オープンリダイレクト や サーバーサイドリクエストフォージェリ (SSRF) に対して脆弱になる可能性があります。
サンプル Web アプリケーションには、2 つの脆弱なエンドポイントが含まれています。
最初のエンドポイント /redirect は、Spring の異常な URL 解析がどのようにオープンリダイレクトを引き起こすかを示しています。これは次のような URL を使用して悪用できます:
https://127.0.0.1[@evil.com
2 番目のエンドポイント /health-check は、Spring と Java 標準ライブラリの URL クラスとの間の URL 解析の不一致がどのようにサーバーサイドリクエストフォージェリ (SSRF) を引き起こすかを示しています。これは次のような URL を使用して悪用できます:
https://evil.com[@127.0.0.1
Maven でこのプロジェクトをビルドするには、次のコマンドを実行するだけです(OpenJDK 17 でテスト済み):
mvn clean package
次に、以下のようなコマンドで Web アプリを起動します:
java -jar seanpesce-cve-2024-22243.jar 9999
Web アプリには http://127.0.0.1:9999/ でアクセスできます。
Docker イメージをビルドするには、次のコマンドを実行します:
docker build -t seanpesce-cve-2024-22243:latest .
次に、以下のようなコマンドで Web アプリを起動します:
docker run -i -e PORT=9999 -p 9999:9999 seanpesce-cve-2024-22243:latest
Web アプリには Docker ホスト上の http://127.0.0.1:9999/ でアクセスできます。
このリポジトリには、脆弱な可能性のあるコードパスをスキャンするための semgrep ルールも含まれています。spring-cve-2024-22243_loose.yaml は、脆弱な API の使用を単純にスキャンします。そのため、多くの偽陽性を返すことがよくあります。spring-cve-2024-22243_strict.yaml は、より厳密なロジックと汚染分析を使用しようとします。ただし、これは十分にテストされておらず、一部の脆弱な実装を見逃す可能性が高くなります(特に、ファイル間分析に必要な Semgrep Pro を使用していない場合)。