Javaプロジェクトの既知脆弱性をMCP経由で確認できる「OSV-Scanner-MCP」の v0.3.0 をnpmで公開しました。
今回追加したのは、既存のSBOMを入力にする scan_sbom ツールです。CycloneDX / SPDXのJSONに記録された依存を、Google製OSV-Scannerで検査できます。
なぜSBOM入力を追加したのか
これまでは、Javaプロジェクトを対象にする scan_java_project と、JAR / WARの実体を対象にする scan_java_artifact を提供していました。
ただし、アーカイブ内のメタデータだけでは依存を十分に識別できない場合があります。
特にshaded / fat JARでは、手元の成果物からどのライブラリが含まれるかを把握しにくいことがあります。
そこで、ビルド時に生成したSBOMがある場合に、その依存情報を別の入力として利用できるようにしました。
SBOMがあれば網羅性を保証できる、という意味ではありません。 対象の成果物と同じビルドに対応する、正確なSBOMを用意する必要があります。
新ツール scan_sbom
MCPクライアントから、次の引数で呼び出します。
{
"sbom_path": "/absolute/path/to/bom.json"
}
対応形式は次のとおりです。
| 形式 | 対応バージョン |
|---|---|
| CycloneDX JSON | 1.4 / 1.5 / 1.6 |
| SPDX JSON | 2.2 / 2.3 |
入力は16 MiB以下のUTF-8 JSONファイルで、ローカルの絶対パスを指定します。XML、SPDX tag-value、SPDX 3には対応していません。
CycloneDXの components[].purl、SPDXの packages[].externalRefs には、バージョン付きPackage URLを含めてください。例えばLog4jなら pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1 です。
このツールは SBOMの生成やビルド、JARの実行は行いません。SBOMは別途生成したものを使用します。
導入と呼び出し
Node.js 20.19以上が必要です。既存のMCPクライアント設定では、サーバーの起動コマンドを npx、引数を以下のように指定するとv0.3.0を利用できます。
["-y", "osv-scanner-mcp@0.3.0"]
設定ファイルの構造はクライアントによって異なるため、READMEのセットアップ手順を参照してください。バージョンを変更した場合は、MCPサーバーを再起動してください。
許可するスキャン範囲は、サーバーの環境変数で制限できます。
{
"OSV_MCP_ALLOWED_ROOT": "/absolute/path/to/projects",
"OSV_MCP_REQUIRE_ALLOWED_ROOT": "1"
}
設定後は、例えば次のように依頼できます。
/absolute/path/to/projects/example/target/bom.jsonをscan_sbomで検査し、検出した脆弱性と識別できなかったパッケージを説明してください。
スキャン時にはOSVへのネットワーク照会が発生します。オフライン完結の検査ではありません。
結果の読み方: 検出ゼロと安全は別
レポートには脆弱性の一覧だけでなく、スキャンの範囲を示す coverage を含めています。
| 項目 | 意味 |
|---|---|
identified_package_count |
名前・バージョン・エコシステムを識別できたパッケージ数。重複を除き、既知脆弱性がないものも含む |
unidentified_packages |
スキャナー出力に存在するものの、識別情報が不足しているパッケージ |
completeness |
not_verified: SBOMの網羅性は未検証 |
artifact_match |
not_verified: 実成果物との一致は未検証 |
スキャナー自体が読み飛ばした項目は、unidentified_packages にも出ない場合があります。この配列が空でも、SBOM内のすべてを検査できたとは限りません。
また、入力したSBOMの形式、仕様バージョン、SHA-256を返します。このハッシュは「どの入力バイト列を検査したか」を追跡するためのもので、SBOMの真正性やJARとの一致を証明するものではありません。
入力処理で行っている対策
- 許可ルートと通常ファイルであることの確認
- 読み込み途中にも適用する16 MiBのサイズ制限
- 権限を制限した一時コピーのみをスキャンし、成功・失敗のどちらでも削除
- 既存のスキャンと共通のタイムアウト、出力上限、同時実行制限
JSONの形式と主要構造は確認しますが、仕様全体に対するJSON Schema検証ではありません。これらの対策は、未知の入力に対する安全性を無条件に保証するものではありません。
fat JARとSBOMを照合してみた
機能追加に合わせて、別のテスト用Mavenプロジェクトで照合を行いました。既知脆弱性のある依存を含む検証専用のプロジェクトで、アプリケーションとしては実行していません。
- CycloneDX Maven plugin 2.9.3でCycloneDX 1.6のSBOMを生成
- Maven Shade plugin 3.6.2で依存を展開したfat JARを生成
- 元の依存JARのSHA-256をSBOMと照合
- 元の依存JARとfat JARのクラスをバイト列で照合
-
scan_sbomとscan_java_artifactの検出結果を比較
結果は以下のとおりです。
| 確認対象 | 結果 |
|---|---|
| 依存JARのSHA-256 | 7依存すべてSBOMと一致 |
| fat JAR内の依存クラス | 5,683クラスのバイト列が一致 |
| 脆弱性の検出結果 | パッケージ・バージョン・脆弱性ID等の組み合わせ17件が一致 |
| 照合処理の正常系・異常系テスト | 8件成功 |
異常系では、クラスの欠落・改変・追加、SBOMハッシュの不一致、Mavenメタデータの欠落・改変、依存項目の重複を検出できることを確認しました。
この照合は製品の新しい自動保証機能ではなく、外部のテスト用スクリプトによる検証です。 テスト用プロジェクトにはアプリケーションクラスがなく、クラスの名前変更や削減も行っていません。署名、モジュール記述子、その他のリソースは照合対象外です。検証スクリプトはnpmパッケージには含まれません。
17件という数は検証時点のOSVデータに依存し、将来の照会では変わる可能性があります。
まとめ
v0.3.0では、プロジェクトやJAR / WARに加えて、SBOMを入口にした脆弱性検査ができるようになりました。
重視したのは、検出結果だけでなく「識別できた範囲」と「まだ保証できないこと」を明示することです。ビルド成果物とSBOMをセットで管理しているJavaプロジェクトで、MCP経由の確認に活用していただければと思います。
不具合や改善案はGitHub Issuesでお知らせください。