依存ライブラリ管理とSCA。SBOMで攻撃面を把握する
対象の目安: Webアプリ開発者・DevOps/プラットフォーム担当 / 実務レベル

現代のアプリケーションは、自分たちが書いたコードよりも、外部から取り込んだライブラリのほうが行数も依存関係も多いのが普通です。npmやpip、Maven、Goのモジュールを少しインストールしただけで、その先にある間接的な依存(依存先がさらに依存しているもの)まで含めると、数百から数千のパッケージが自分のアプリの一部として動いています。この「自分で書いていないのに自分の責任になるコード」をどう把握し、どう守るかが、サプライチェーンセキュリティの出発点です。
ここで鍵になるのが、SBOM(Software Bill of Materials、ソフトウェア部品表)とSCA(Software Composition Analysis、ソフトウェア構成分析)という二つの考え方です。SBOMは「自分のアプリが何でできているか」を機械可読な台帳として書き出すこと、SCAは「その部品の中に既知の脆弱性を持つものがないか」を脆弱性データベースと突き合わせて見つけることです。台帳がなければ突き合わせる対象が分からず、突き合わせがなければ台帳はただのリストで終わります。両者は車の両輪です。
この記事では、SBOMの代表的な2つの標準であるSPDXとCycloneDXの違い、SCAがどんな原理で脆弱性を見つけ何を見落とすのか、DependabotやRenovateによる依存更新の自動化、そしてこれらをCI/CDにどう組み込み、どこで「ビルドを止める/止めない」を線引きするかという実務の判断基準まで、原理から噛み砕いて整理します。Log4Shellのような事件がなぜあれほど広範囲に及んだのかを思い出しながら読むと、SBOMの価値が腹落ちするはずです。
まず全体像を、SBOMとSCAおよび更新自動化が「何を担い、何を入力に、何を出力するか」という観点で一覧にします。
| 要素 | 役割 | 主な入力 | 主な出力 | 代表的な実装例 |
|---|---|---|---|---|
| SBOM生成 | 構成部品の台帳化 | ロックファイル・ビルド成果物・コンテナイメージ | SPDX/CycloneDX形式のファイル | Syft, cdxgen, 各言語のSBOMプラグイン |
| SCA(脆弱性突合) | 既知脆弱性の検出 | SBOMまたは依存情報 | 脆弱性レポート(CVE/GHSA一覧) | OWASP Dependency-Check, Trivy, Grype, osv-scanner |
| 更新自動化 | 脆弱な版の置き換え | 依存マニフェスト・脆弱性アラート | 更新プルリクエスト | Dependabot, Renovate |
| 脆弱性DB | 突合の参照元 | CVE・各エコシステムの勧告 | パッケージ/版と脆弱性の対応 | NVD, GitHub Advisory(GHSA), OSV.dev |
この4つが連携して初めて、「何を使っているか把握し(SBOM)、その中の危険を見つけ(SCA)、安全な版へ置き換える(更新自動化)」という一連の流れが回ります。以下、それぞれを掘り下げます。
なぜSBOMが必要なのか。Log4Shellが示した「把握できていない」リスク
SBOMの価値が最もはっきり分かったのが、2021年末のLog4Shell(Apache Log4jの脆弱性、CVE-2021-44228)でした。多くの組織がまず直面したのは「自社の製品やシステムのどこでLog4jを使っているのか分からない」という問題でした。直接依存していなくても、別のライブラリやミドルウェアが内部でLog4jを使っているケースが多く、影響範囲の特定そのものに何日もかかった組織が少なくありません。詳しくは あわせて読みたい Log4Shellに学ぶ、依存ライブラリ脆弱性の怖さとSBOM・SCAによる対策
ここで効くのがSBOMです。各システムについて「使っている部品の一覧」を機械可読な形で保管しておけば、新しい脆弱性が公表された瞬間に「log4j-coreのこのバージョンを含む成果物はどれか」を一覧で検索できます。人手で各プロジェクトのビルド設定を開いて回る作業が、台帳への問い合わせ一回に置き換わるわけです。これは攻撃を防ぐ仕組みというより、事故が起きたときの初動を速くする仕組みだと理解すると正確です。
SBOMの典型的な記載項目は、コンポーネント名、バージョン、サプライヤー、一意な識別子(後述のPURLなど)、ライセンス、ハッシュ値、依存関係などです。重要なのは、これらが「人が読むためのドキュメント」ではなく「機械が処理するためのデータ」である点です。だからこそ標準フォーマットが定められています。
注意
SBOMは作って終わりではありません。ビルドのたびに依存は変わるため、リリースごとに自動生成し、成果物と一緒に保管する運用にしないと、いざというとき「古い台帳しかない」状態になります。SBOMは生鮮品だと考え、CI/CDで毎回作り直すのが基本です。
SBOMの2大標準。SPDXとCycloneDXの違い
SBOMのフォーマットは事実上、SPDXとCycloneDXの2つが標準として広く使われています。どちらが優れているという話ではなく、出自と得意分野が違います。
SPDXはLinux Foundationが主導するプロジェクトで、もともとオープンソースのライセンスやコンプライアンス管理を起点に発展しました(略称の正式名称は2.x系までのSoftware Package Data Exchangeから、3.0系でSystem Package Data Exchangeへと再定義されています)。SPDXはISO/IEC 5962:2021として国際標準にもなっています(このISO標準はSPDX 2.2.1がベース)。その後、モデルを大きく刷新したSPDX 3.0が2024年4月に公開され、執筆時点では3.0.1が最新の安定版です。3.0ではSecurity Profileが整備され、脆弱性やVEX関連の情報も扱えるようになりました。ライセンス情報の詳細な記述に強く、法務・コンプライアンス観点での部品表として根強い支持があります。
CycloneDX はOWASPコミュニティ発のプロジェクトで、こちらはセキュリティを起点に設計されています。国際標準としてはECMA-424として標準化されており、SBOMだけでなくVEX(Vulnerability Exploitability eXchange、脆弱性が実際に悪用可能かを伝える形式)や、SaaSBOM・CBOM(暗号部品表)・AI/ML-BOMといった派生にも対応します。脆弱性との連携を最初から想定しているため、SCAや攻撃面の把握という文脈ではCycloneDXを選ぶ現場が多い傾向です。
| 観点 | SPDX | CycloneDX |
|---|---|---|
| 主導 | Linux Foundation | OWASP |
| 標準化 | ISO/IEC 5962:2021(2.2.1ベース)、3.0系が最新 | ECMA-424 |
| 起点・得意 | ライセンス/コンプライアンス | セキュリティ/脆弱性連携 |
| VEX対応 | 3.0のSecurity Profileで対応 | ネイティブに対応 |
| よく使う場面 | OSSライセンス監査、調達要件 | SCA、脆弱性管理、攻撃面把握 |
実務上の選び方はシンプルです。ライセンスコンプライアンスや顧客・規制からの提出要件が主目的ならSPDX、社内のセキュリティ運用(脆弱性検出やVEX運用)が主目的ならCycloneDX、という分け方で問題ありません。両方を生成できるツールも多いので、迷うなら片方に固定せず両形式で出力しておく手もあります。
なお、フォーマットをまたいで部品を一意に識別する仕組みとしてPURL(Package URL)がよく使われます。pkg:npm/lodash@4.17.21 のように「エコシステム/パッケージ名/バージョン」を一意な文字列で表すもので、SBOMとSCAをつなぐ共通言語として機能します。
「SPDXとCycloneDX、どちらを採用すべきか」で議論が止まる現場をよく見ます。ですが本質はフォーマット選びではなく、SBOMを毎ビルド自動生成して保管し、脆弱性が出たときに検索できる運用を持っているかどうかです。形式は後から変換もできます。まず一本、自動生成のパイプラインを通すことを優先してください。
SCAの原理。何を見つけ、何を見落とすのか
SCA(ソフトウェア構成分析)は、依存ライブラリの一覧やSBOMを脆弱性データベースと突き合わせ、「既知の脆弱性を持つ版を使っていないか」を検出します。ここで大事なのは、SCAが見つけるのは原則として「公表済みの既知の脆弱性」だという点です。未知の脆弱性(ゼロデイ)や、あなたの自作コードのバグは対象外です。SCAは あわせて読みたい DevSecOps入門。CI/CDにセキュリティを組み込むSAST・DAST・SCA・シークレットスキャン
突合の参照元となる脆弱性データベースには、主に次のものがあります。
- NVD(National Vulnerability Database)。NISTが運営する米国政府の脆弱性カタログで、CVEに紐づく情報の中心。CPE(製品識別子)でのマッチングが特徴。
- GitHub Advisory Database(GHSA)。npm・PyPI・Maven・RubyGems・NuGet・Go・Composer・Rust などエコシステム単位で整理された勧告。
- OSV.dev。GoogleとOpenSSFが関わる分散型データベースで、OSVスキーマにより「どのパッケージのどのバージョン範囲が影響を受けるか」を機械可読・高精度で表現する。
検出方式には大きく2系統あります。ひとつはNVDのCPEに基づくマッチングで、OWASP Dependency-Checkが代表例です。これはライブラリから推定したCPE識別子をCVEに突き合わせるため、エコシステム固有DBが拾わないものまで拾える一方、推定がゆるい分、誤検知(実際には該当しないのに警告が出る)が増えやすい傾向があります。もうひとつは、ロックファイルのパッケージ名とバージョンをエコシステム固有の勧告(GHSAやOSV)に直接突き合わせる方式で、Trivy・Grype・osv-scannerなどが採用します。こちらは精度が高く誤検知が少ない反面、DBが対応していないエコシステムや、CVEはあるが勧告化されていないものを取りこぼすことがあります。
| ツール | 主な検出方式 | 得意領域 | 注意点 |
|---|---|---|---|
| OWASP Dependency-Check | NVD/CPEマッチング | Java/.NET等、広く拾う | 誤検知が比較的多い |
| Trivy | エコシステム勧告+α | コンテナ・IaC・依存を横断 | 設定次第で出力が多くなる |
| Grype | エコシステム勧告(GHSA/OSV等) | 依存・コンテナの精度重視 | 対応エコシステム依存 |
| osv-scanner | OSVスキーマ突合 | ロックファイル・SBOM入力 | OSV未収録分は取りこぼし |
ここから導かれる実務的な教訓は、「1つのツールだけに頼らない」ことと、「検出結果を鵜呑みにせず誤検知を前提に運用する」ことです。誤検知は無視するのではなく、なぜ該当しないのかを記録(VEXや抑制設定)に残すことで、次回以降のノイズを減らせます。
依存更新の自動化。DependabotとRenovate
脆弱性を見つけても、安全な版に置き換えなければ攻撃面は減りません。しかし依存の更新は手間がかかり、後回しにされがちです。これを「プルリクエスト(PR)が勝手に上がってくる」状態にして、レビューとマージだけに集中できるようにするのが更新自動化ツールです。
GitHubに統合されているDependabotは、用途の異なる2つの機能を持ちます。ひとつはバージョン更新(version updates)で、dependabot.yml という設定ファイルを置くと、脆弱性の有無にかかわらず依存を定期的に最新へ追従するPRを作ります。もうひとつはセキュリティ更新(security updates)で、Dependabotアラートが検出した脆弱な依存について、依存グラフを壊さずに直せる最小限のパッチ版へ更新するPRを自動で作成し、アラートに紐づけます。設定では更新頻度(daily/weekly等)、対象エコシステム、無視するパッケージ、メジャー/マイナー/パッチの粒度などを制御できます。
Renovate(Mendが提供するオープンソースツール)はDependabotより設定の自由度が高く、複数の更新をまとめる(グルーピング)、自動マージの条件を細かく決める、対応するパッケージマネージャが幅広いといった特徴があります。GitHub以外のプラットフォームでも使いやすいのが利点です。どちらを選ぶかは、GitHub中心で手軽に始めたいならDependabot、細かな運用ポリシーを作り込みたいならRenovate、という整理でおおむね合います。
# .github/dependabot.yml の最小例
# npmの依存を毎週チェックし、更新PRを自動で作成する
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
注意
自動更新で見落としがちなのが、PRが増えすぎて誰もレビューしなくなる「PR疲れ」と、テストが不十分な状態での自動マージです。更新が壊れていないかを担保するのは結局テストです。CIのテストが薄いまま自動マージを有効にすると、安全のための仕組みが新しい不具合の入口になります。自動化の前にテストの整備を、という順序を崩さないでください。
CIへの組み込みと「止める/止めない」の判断基準
SBOM生成・SCA・更新自動化は、CI/CDに組み込んで初めて継続的に効きます。組み込みの基本形は次の通りです。
- ビルド時にSBOMを自動生成し、成果物と一緒に保管する。
- そのSBOM(または依存情報)に対してSCAを実行し、脆弱性レポートを出す。
- Dependabot/Renovateで更新PRを継続的に上げ、マージで攻撃面を減らす。
ここで現場が必ず迷うのが、「脆弱性が見つかったらビルドを失敗させるべきか」です。結論から言うと、最初から全件で失敗させるのは避けるべきです。導入直後は既存の依存に大量の指摘が出るのが普通で、いきなり全部を失敗扱いにすると開発が止まり、現場は「とりあえずスキップ」を覚えてしまいます。これではせっかくの仕組みが形骸化します。
現実的な進め方は、重大度と「修正版があるか(fix available)」を軸にしたしきい値の段階的な引き上げです。たとえば最初は「Critical かつ修正版あり」だけをビルド失敗の条件にし、それ以外は警告として記録に残します。運用が回り始めたらHighまで広げる、というように厳格化を後追いさせます。重大度の評価にはCVSSが使われますが、スコアだけで機械的に判断せず、実際に悪用可能か(攻撃経路に乗っているか)を加味するのが望ましく、ここでVEXが役立ちます。CVSSの読み方は あわせて読みたい CVSSスコアの読み方と脆弱性対応の優先度付け。基本値だけで判断しないために
「脆弱性ゼロ」を目標に掲げると、達成不能な理想に現場が疲弊します。目指すべきは脆弱性ゼロではなく、『重大なものを、許容できる時間内に、確実に直し切れる流れ』を持っていることです。SBOMとSCAは、その流れを支える可視化と検出の土台だと位置づけると、運用が長続きします。
このテーマはサプライチェーン攻撃全体の一部でもあります。依存ライブラリそのものが乗っ取られる、いわゆる悪意ある更新や typosquatting などの手口は あわせて読みたい サプライチェーン攻撃の構造と防御の考え方。ソフト・ハード・サービス経由の侵入をどう減らすか
よくある質問
SBOMとSCAは何が違うのですか。
SPDXとCycloneDX、どちらを選べばよいですか。
SCAを入れれば脆弱性は防げますか。
検出された脆弱性が誤検知のようです。どう扱えばよいですか。
いきなりCIでビルドを失敗させても大丈夫ですか。
まとめ
依存ライブラリ管理は「何を使っているかを台帳化(SBOM)し、その中の危険を見つけ(SCA)、安全な版へ置き換える(更新自動化)」という流れを、CI/CDで継続的に回すことに尽きます。検出だけで満足せず、直し切る流れまで作って初めて攻撃面が減ります。なお脆弱性対応の手順や重大度の判断は状況により変わるため、実際の対応にあたっては各ツール・データベースの最新の公式情報、および自社の法務・セキュリティ専門家に確認したうえで進めてください。
依存管理とSCA導入チェックリスト
- ビルドのたびにSBOMを自動生成し、成果物と一緒に保管しているか
- SBOMの形式(SPDX/CycloneDX)を目的に合わせて選んでいるか、両形式を出力しているか
- SCAを少なくとも1つCIに組み込み、脆弱性レポートを出しているか
- DependabotまたはRenovateで更新PRが継続的に上がる状態になっているか
- 自動マージの前提となるテストが十分に整備されているか
- ビルド失敗のしきい値を重大度と修正版有無で段階的に設計しているか
- 誤検知をVEXや抑制設定として記録し、ノイズを減らす運用があるか
- 新しい脆弱性公表時にSBOMから影響範囲を即座に検索できる状態か
出典・参考
関連する記事
Log4Shellに学ぶ、依存ライブラリ脆弱性の怖さとSBOM・SCAによる対策
Apache Log4jのCVE-2021-44228(Log4Shell)を題材に、依存ライブラリの脆弱性がなぜ広範な被害を生むのかを原理から解説し、SBOMとSCAを軸にしたサプライチェーンの脆弱性管理を実務目線で整理します。
サプライチェーン攻撃の構造と防御の考え方。ソフト・ハード・サービス経由の侵入をどう減らすか
自社が直接狙われなくても、取引先やライブラリ、サービス経由で侵入されるのがサプライチェーン攻撃です。実例をもとに攻撃の構造を分解し、信頼の前提を見直すための実務的な防御の考え方を解説します。
DevSecOps入門。CI/CDにセキュリティを組み込むSAST・DAST・SCA・シークレットスキャン
セキュリティを開発の最後の検査にせず、CI/CDに自動チェックとして組み込む考え方を解説します。SAST・DAST・SCA・シークレットスキャンの役割の違いと、シフトレフトを現場で回す導入順序・判断基準を具体的にまとめます。


