Spring Bootでレガシーなアプリケーションを運用しているエンジニアや、依存関係の脆弱性スキャン結果をどう読めばよいか迷っている方に向けた内容です。CVSS(脆弱性の深刻度を0〜10で示す共通指標)9.8という数字だけを見ても、実際に何が起きるのかは分かりにくいものです。この記事では、実際のレガシーJavaアプリケーション「MFlix」に対するSnyk(依存関係の脆弱性を検出するスキャンツール)の結果をもとに、なぜその脆弱性が危険なのか、自分のプロジェクトが該当するかどうかをどう確認すればよいかを整理します。
何が起きるか — RCEという最悪カテゴリ
MFlixのスキャン結果には、10件のCritical(緊急)、99件のHigh(重大)を含む188件の脆弱性が検出されました。
その中でも特に注目すべきは、org.springframework:[email protected] に存在するRCE(Remote Code Execution、リモートからの任意コード実行)です。
RCEは、攻撃者が対象サーバー上で任意のコマンドを実行できる状態を指します。
CVSS 9.8は理論上の最大値である10にほぼ近く、「情報漏えいの可能性がある」レベルではなく「サーバーを乗っ取られる」レベルの脆弱性です。
MFlixは映画検索と認証エンドポイントを認証不要(未ログインでもアクセス可能)で公開しています。
つまり攻撃者は資格情報を持たなくても、脆弱なコードパスに到達できる公開API経由の攻撃面を持っています。
もう1件、org.apache.tomcat.embed:[email protected] にもCVSS 9.8の脆弱性があります。
こちらはAJP(Apache JServ Protocol、Webサーバーとアプリケーションサーバー間の通信プロトコル)コネクタの安全でないデフォルト設定に起因するものです。
Spring Bootは組み込みTomcatをデフォルトで同梱するため、pom.xml に明示的な記述がなくても影響を受けます。
なぜ起きるか — 直接依存と推移的依存の見落とし
この手のRCEが放置される背景には、いくつかの段階的な原因があります。
第一に、脆弱性が直接依存ではなく推移的依存(間接的に取り込まれるライブラリ)に潜んでいる点です。tomcat-embed-core は [email protected] を介して間接的に取り込まれており、pom.xml を目視で確認しても直接見つかりません。
開発者が「自分はspring-boot-starter-webしか書いていない」と思っていても、そこから連鎖する依存の中に危険なバージョンが混ざっています。
第二に、Spring4Shell(CVE-2022-22965)と混同されやすい点です。
Spring4Shellは2022年に大きく報道された脆弱性で、Java 9以上・Spring Framework 5.3.xまたは5.2.x・TomcatへのWARデプロイ・特定のSpring MVC設定という前提条件が必要でした。
一方、[email protected] のRCEは前提条件こそ異なりますが、同じ「クラスパス式を悪用したコード実行」という脆弱性の系統に属します。
名前が似た脆弱性のパッチ適用状況だけを見て「対応済み」と誤認するケースが起こりえます。
第三に、レガシーアプリケーションではBOM(Bill of Materials、依存バージョンをまとめて管理する仕組み)を使わず、個別にバージョンを固定しているケースが少なくありません。
Spring BootのBOMを使っていれば、Spring Boot本体を2.7.x系や3.x系に上げるだけで関連ライブラリのバージョンも連動して引き上がります。
BOMを使わず個別指定していると、1つずつ手動でバージョンを追跡する必要があり、更新漏れが発生しやすくなります。
自分のプロジェクトが該当するか確認する
実際に確認する手順は次の通りです。
# Mavenプロジェクトで依存関係ツリーを出力し、
# spring-beansとtomcat-embed-coreのバージョンを確認する
mvn dependency:tree | grep -E "spring-beans|tomcat-embed-core"# Gradleプロジェクトの場合
./gradlew dependencies | grep -E "spring-beans|tomcat-embed-core"出力に spring-beans が 5.2.20.RELEASE 未満、あるいは tomcat-embed-core が旧8.5系の初期バージョンで表示された場合は、該当する可能性が高い状態です。
さらに、pom.xml や build.gradle の spring-boot-starter-parent や spring-boot-dependencies のバージョン表記も確認してください。
2.0系や2.1系のような古い記載がある場合、内包するライブラリ群も古いままの可能性が高くなります。
SnykやOWASP Dependency-Check(無料で使えるオープンソースの依存関係スキャンツール)を導入していない場合は、まずスキャンを実行し、CVSSスコアとCWE(Common Weakness Enumeration、脆弱性の種類分類)番号を出力させることから始めるのが実務的です。
CWE-94(コード生成の不適切な制御)やCWE-453(安全でないデフォルト変数初期化)のようなタグが出た場合、それは「設定ミス」ではなく「設計上の欠陥」に近いものだと捉えておくと判断がぶれません。
対策の手順
確認の結果、該当するバージョンが見つかった場合の対応手順です。
spring-webを5.2.20.RELEASE以降に上げる(Spring Boot 2.7.x以上へのアップグレードで連動して解決)- Spring BootのBOMを使っている場合は、
spring-boot-starter-parentのバージョンを最新の安定版に上げる - BOMを使っていない場合は、この機会に個別バージョン指定からBOM管理へ移行を検討する
- AJPコネクタを使っていない構成であれば、
server.tomcat.ajp.enabled=falseのような設定でコネクタ自体を無効化する - アップグレード後は必ずSnykなどで再スキャンし、Priority Score(優先度スコア)が下がったことを確認する
アップグレードには互換性の問題がつきまといます。
Spring Boot 2.0系から2.7系への移行は、設定プロパティ名の変更やJava 8から11以降への移行を伴うことがあるため、まずステージング環境で回帰テストを通してから本番反映するのが安全です。
技術的負債という観点では、こうした古いバージョンの放置は「後で直せばいい」という判断の積み重ねの結果です。
CVSS 9.8の脆弱性が2件も未対応のまま公開エンドポイントの背後に存在する状態は、可用性やセキュリティのトレードオフというより、単純にリスクの見積もりが甘かったサインと考えられます。
確認すべきことのまとめ
レガシーなSpring Bootアプリケーションを抱えている場合、次の3点を確認してみてください。
mvn dependency:treeまたはgradlew dependenciesでspring-beansとtomcat-embed-coreのバージョンを洗い出す- 見つかった脆弱性が未認証エンドポイントの背後にあるかどうかを脅威モデルとして整理する
- BOMベースの依存管理に移行し、Spring Boot本体のバージョンアップで連動更新できる体制を作る
188件という数字に圧倒される前に、まずはCVSSが高く、かつ公開APIから到達可能なものだけを優先的に洗い出すところから始めてみてください。