SBOMと脆弱性診断
SBOM(ソフトウェア部品表)とは
SBOM(Software Bill of Materials) とは、ソフトウェアを構成するすべてのコンポーネント・ライブラリ・依存関係を一覧化した「部品表」です。
製造業における部品表(BOM)と同様に、SBOMはソフトウェアの「原材料」を明確にします。
アプリケーション
├── フレームワーク (例: ASP.NET Core 9.0)
├── ライブラリA v1.2.3
│ └── transitiveな依存A1 v0.5.0
├── ライブラリB v2.0.1
│ ├── transitiveな依存B1 v1.0.0
│ └── transitiveな依存B2 v3.1.2
└── ...(数十〜数百のコンポーネント)
主要なSBOMフォーマット
| フォーマット | 開発元 | 特徴 |
|---|---|---|
| CycloneDX | OWASP | セキュリティ特化、軽量 |
| SPDX | Linux Foundation | ライセンス管理にも強い |
| SWID | ISO/IEC 19770-2 | 主に企業資産管理向け |
現在のセキュリティ文脈では CycloneDX と SPDX が主流です。
SBOMとセキュリティの関係
なぜSBOMが重要か
2021年5月、米国バイデン大統領は「国家サイバーセキュリティ改善に関する大統領令(EO 14028)」を発令し、政府機関への納入ソフトウェアにはSBOMの提供を義務付けました。これをきっかけに、世界的にSBOMへの注目が高まっています。
Log4Shell(CVE-2021-44228)の教訓
2021年末に発覚したLog4Shellは、SBOMの重要性を示す典型例です。
- 影響範囲: Java製アプリケーションのほぼすべて
- 問題:
log4jは直接依存ではなく推移的依存として組み込まれることが多く、把握が困難 - SBOMがあると: 影響を受けるアプリケーションを数分で特定可能
- SBOMがないと: 全サービスを手動で調査する必要があり、数週間かかるケースも
SCA(ソフトウェアコンポジション解析)
SCA(Software Composition Analysis)は、SBOM生成および依存関係の脆弱性を自動検出する技術です。
主要な脆弱性データベース
| データベース | URL | 特徴 |
|---|---|---|
| NVD | nvd.nist.gov | 米国政府管理、CVE番号付き |
| OSV | osv.dev | オープンソース脆弱性に特化 |
| GitHub Advisories | github.com/advisories | GitHub管理、SCAと統合しやすい |
| JVNDB | jvndb.jvn.jp | 日本のIPA管理 |
.NET の脆弱性診断
dotnet list package --vulnerable
.NET CLIに組み込まれた脆弱性チェック機能です。
# 直接依存の脆弱性チェック
dotnet list package --vulnerable
# 推移的依存も含めてチェック(推奨)
dotnet list package --vulnerable --include-transitive
# 出力例
# Project `MyApp` has the following vulnerable packages
# [net9.0]:
# Top-level Package Requested Resolved Severity Advisory URL
# > Newtonsoft.Json 13.0.1 13.0.1 High https://github.com/...
SBOM生成 with CycloneDX
# CycloneDX .NET ツールのインストール
dotnet tool install --global CycloneDX
# SBOM生成(CycloneDX JSON形式)
dotnet CycloneDX MyProject.csproj -o ./sbom -j
# SBOM生成(SPDX形式)
dotnet CycloneDX MyProject.csproj -o ./sbom --SpdxVersion 2.3
生成される bom.json の例(抜粋):
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"timestamp": "2026-03-23T10:00:00Z",
"component": {
"type": "application",
"name": "MyApp",
"version": "1.0.0"
}
},
"components": [
{
"type": "library",
"name": "Newtonsoft.Json",
"version": "13.0.3",
"purl": "pkg:nuget/Newtonsoft.Json@13.0.3",
"licenses": [{ "license": { "id": "MIT" } }]
}
]
}
GitHub Dependabot との連携
.github/dependabot.yml でNuGetパッケージの自動更新を設定できます。
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "dependencies"
- "security"
CI/CDへの統合(GitHub Actions)
name: Security Scan - .NET
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 0 * * 1' # 毎週月曜日
jobs:
vulnerability-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
- name: Restore dependencies
run: dotnet restore
- name: Check for vulnerable packages
run: dotnet list package --vulnerable --include-transitive
- name: Install CycloneDX
run: dotnet tool install --global CycloneDX
- name: Generate SBOM
run: dotnet CycloneDX ./MyProject.csproj -o ./sbom -j
- name: Upload SBOM artifact
uses: actions/upload-artifact@v4
with:
name: sbom
path: ./sbom/bom.json
Docker / コンテナの脆弱性診断
コンテナイメージはOSパッケージ・言語パッケージの両方を含むため、SBOMと脆弱性診断が特に重要です。
Trivy によるスキャン
Trivy はAqua Security社製のオールインワンセキュリティスキャナーです。
# イメージのスキャン
trivy image myapp:latest
# CRITICAL・HIGHのみ表示
trivy image --severity CRITICAL,HIGH myapp:latest
# SBOM生成(CycloneDX形式)
trivy image --format cyclonedx --output sbom.json myapp:latest
# SBOM生成(SPDX形式)
trivy image --format spdx-json --output sbom.spdx.json myapp:latest
# ファイルシステムスキャン(ソースコードディレクトリ)
trivy fs --security-checks vuln,secret ./
# 設定ファイルスキャン(Dockerfile, Kubernetes YAML等)
trivy config ./
出力例:
myapp:latest (ubuntu 22.04)
=========================
Total: 5 (CRITICAL: 1, HIGH: 4)
┌───────────────┬──────────────────┬──────────┬────────────────────┬───────────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version │ Fixed Version │
├───────────────┼──────────────────┼──────────┼────────────────────┼───────────────────┤
│ openssl │ CVE-2024-XXXX │ CRITICAL │ 3.0.2-0ubuntu1.13 │ 3.0.2-0ubuntu1.14 │
│ libssl3 │ CVE-2024-XXXX │ HIGH │ 3.0.2-0ubuntu1.13 │ 3.0.2-0ubuntu1.14 │
└───────────────┴──────────────────┴──────────┴────────────────────┴───────────────────┘
Grype によるスキャン
Grype はAnchore社製のコンテナ・SBOMスキャナーです。
# イメージスキャン
grype myapp:latest
# SBOMファイルのスキャン(Trivyなどで生成したSBOMを再スキャン)
grype sbom:./sbom.json
# SBOM生成には Syft を使用
syft myapp:latest -o cyclonedx-json > sbom.json
syft myapp:latest -o spdx-json > sbom.spdx.json
Dockerfileのベストプラクティス
脆弱性を最小化するDockerfileの書き方:
# NG: 大きなベースイメージ(脆弱性の表面積が大きい)
FROM ubuntu:22.04
# OK: ディストロレスイメージ(OSパッケージなし、最小限)
FROM gcr.io/distroless/dotnet-runtime:9
# OK: Alpine(軽量、脆弱性が少ない)
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine
# マルチステージビルドで本番イメージを最小化
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS runtime
WORKDIR /app
# 非rootユーザーで実行(セキュリティ強化)
USER $APP_UID
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.dll"]
GitHub Actions でのコンテナスキャン
name: Container Security Scan
on:
push:
branches: [main]
jobs:
container-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1' # CRITICALまたはHIGHが見つかればビルド失敗
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
- name: Generate SBOM
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'cyclonedx'
output: 'sbom.json'
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: container-sbom
path: sbom.json
Node.js の脆弱性診断
npm audit
npm に組み込まれた脆弱性チェックツールです。
# 脆弱性チェック
npm audit
# 自動修正(互換性のある範囲で更新)
npm audit fix
# 破壊的変更を含む修正(注意が必要)
npm audit fix --force
# JSON形式で出力(CI/CD連携向け)
npm audit --json
# 出力例
# found 3 vulnerabilities (1 moderate, 2 high)
# Run `npm audit fix` to fix them, or `npm audit` for details
npm audit fix --force は意図しないメジャーバージョンアップを引き起こすことがあります。
変更内容を必ず確認してから実行してください。
SBOM生成
# CycloneDX Node.js ツールのインストール
npm install -g @cyclonedx/cyclonedx-npm
# SBOM生成
cyclonedx-npm --output-file sbom.json
# npm-sbom(Node.js v22以降で利用可能)
npm sbom --sbom-format cyclonedx
npm sbom --sbom-format spdx
Socket Security
Socket はnpmパッケージのサプライチェーン攻撃を検出する特化型ツールです。
# インストール
npm install -g @socketsecurity/cli
# スキャン
socket scan npm
GitHub Actions での Node.js スキャン
name: Security Scan - Node.js
on:
push:
branches: [main]
pull_request:
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install dependencies
run: npm ci
- name: Run npm audit
run: npm audit --audit-level=high
# audit-level: low/moderate/high/critical
- name: Generate SBOM
run: |
npm install -g @cyclonedx/cyclonedx-npm
cyclonedx-npm --output-file sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: nodejs-sbom
path: sbom.json
Python の脆弱性診断
pip-audit
Python Packaging Authority (PyPA) が管理する公式の脆弱性スキャナーです。
# インストール
pip install pip-audit
# カレントの仮想環境をスキャン
pip-audit
# requirements.txtを直接スキャン
pip-audit -r requirements.txt
# SBOM形式で出力(CycloneDX)
pip-audit -r requirements.txt -f cyclonedx -o sbom.json
# SBOM形式で出力(SPDX)
pip-audit -r requirements.txt -f spdx-json -o sbom.spdx.json
# 出力例
# Name Version ID Fix Versions
# ------------- -------- -------------- ------------
# requests 2.27.1 GHSA-j8r2-6x86 2.28.0
Safety
# インストール
pip install safety
# 依存関係のスキャン(requirements.txt)
safety check -r requirements.txt
# インストール済みパッケージのスキャン
safety check
# JSON形式で出力
safety check --json
Bandit(静的解析)
Banditは Pythonコードの セキュリティバグ を検出する静的解析ツールです(SCAではなくSAST)。
# インストール
pip install bandit
# ディレクトリをスキャン
bandit -r ./src
# 重大度HIGH以上のみ表示
bandit -r ./src -l -ll
# JSONレポート
bandit -r ./src -f json -o bandit-report.json
Banditが検出する脆弱性の例:
# NG: SQLインジェクションのリスク
query = "SELECT * FROM users WHERE id = " + user_id
cursor.execute(query) # B608: Possible SQL injection
# OK: パラメータ化クエリ
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
# NG: 安全でないデシリアライゼーション
import pickle
data = pickle.loads(user_input) # B301: Pickle and modules that wrap it
# NG: 弱いハッシュアルゴリズム
import hashlib
hashlib.md5(password) # B303: Use of MD5 is insecure
GitHub Actions での Python スキャン
name: Security Scan - Python
on:
push:
branches: [main]
pull_request:
jobs:
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pip-audit bandit
- name: Run pip-audit (SCA)
run: pip-audit -r requirements.txt
- name: Generate SBOM
run: pip-audit -r requirements.txt -f cyclonedx -o sbom.json
- name: Run Bandit (SAST)
run: bandit -r ./src -f json -o bandit-report.json
continue-on-error: true # 結果をアーティファクトとして保存するため
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: python-sbom
path: sbom.json
- name: Upload Bandit report
uses: actions/upload-artifact@v4
with:
name: bandit-report
path: bandit-report.json
ツール比較とまとめ
SBOMおよびSCAツール比較
| ツール | 対象 | SBOM生成 | 脆弱性スキャン | フォーマット |
|---|---|---|---|---|
| Trivy | コンテナ/FS/.git | ✅ | ✅ | CycloneDX, SPDX |
| Syft | コンテナ/FS | ✅ | ❌ | CycloneDX, SPDX |
| Grype | コンテナ/SBOM | ❌ | ✅ | - |
| CycloneDX (.NET) | NuGet | ✅ | ❌ | CycloneDX, SPDX |
| pip-audit | Python | ✅ | ✅ | CycloneDX, SPDX |
| npm audit | npm | ❌ | ✅ | - |
| @cyclonedx/npm | npm | ✅ | ❌ | CycloneDX |
| OWASP Dependency-Check | 多言語 | ✅ | ✅ | CycloneDX, SPDX |
OWASP Dependency-Check(多言語対応)
複数の言語・エコシステムに対応した汎用SCAツールです。
# Dockerで実行
docker run --rm \
-v $(pwd):/src \
-v $(pwd)/reports:/report \
owasp/dependency-check \
--project "MyProject" \
--scan /src \
--format HTML \
--out /report
# GitHub Actionsでの利用
- name: OWASP Dependency Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'MyProject'
path: '.'
format: 'SARIF'
out: 'reports'
args: >
--failOnCVSS 7
--enableRetired
CVSSスコアと対応優先度
CVSS(Common Vulnerability Scoring System)スコアに基づいた優先度付けの目安:
| CVSSスコア | 深刻度 | 対応目安 |
|---|---|---|
| 9.0 - 10.0 | CRITICAL | 即時対応(24時間以内) |
| 7.0 - 8.9 | HIGH | 優先対応(1週間以内) |
| 4.0 - 6.9 | MEDIUM | 計画的対応(次のスプリント) |
| 0.1 - 3.9 | LOW | 余裕があるときに対応 |
- プルリクエスト:
npm audit --audit-level=highなどでCRITICAL/HIGHをブロック - 定期スキャン: 週次・月次でSBOMを生成し、新たに発覚した脆弱性を検出
- コンテナビルド: イメージビルド後に毎回 Trivy でスキャン