Amazon Inspector SBOM Generator 1.6のアップデートによる差分を確認してみた
お疲れさまです。とーちです。
Amazon Inspectorでコンテナイメージスキャンのセキュリティエンジンが強化されたというアップデートがありました
上記の内容を見ただけではどんな変更があったのかさっぱり分かりませんでしたが、よくよく読むとAmazon Inspector SBOM Generatorが新しいエンジンの依存関係コレクションに従って脆弱性を検出するようになったとのこと
更にAmazon Inspector SBOM Generatorのアップデート履歴(ここからダウンロードしたzipファイル内にあるCHANGELOG.md)をみたところ、1/27に1.6にマイナーバージョンアップされていました。これが上記のアップデートと関連があるのかは不明なのですが、この1.6の挙動が前バージョンとどのように違うのか調べてみたので紹介します。
前提知識InspectorとSBOMについて
まずは前提知識として、InspectorとSBOMについておさらいしておきましょう。
2023年6月13日のアップデートで、Amazon InspectorがSBOM(Software Bill of Materials)を生成できるようになりました。これにより以下のことが可能になっています
- ECRなど、環境内の個々のリソースのSBOMをエクスポート可能
- Amazon Inspector SBOM Generatorを使用して、CI/CD環境などでローカルでSBOMを作成し、Inspectorに送信して脆弱性スキャンが可能
なお、SBOMについては、こちらの記事の内容が分かりやすかったです。
SBOM Generator 1.6の主な変更点
SBOM Generatorは以下のページから過去のバージョンも含めインストールすることができるようになっています
最新のバージョン(1.6.1)をダウンロードし、CHANGELOG.md
を見ると以下のような記載がありました。
## [1.6.0] - January 27th 2025
- Improved detection of Node.JS runtimes installed via 3rd party utilities.
- Reduced memory consumption when extracting large files during container scan.
- Sbomgen now collects operating system and kernel information for Bottlerocket OS.
- Improved behavior consistency when scanning container images from various sources (Docker engine, TAR, remote registry).
- Improved error messages when inspector-sbomgen is unable to download a remote image due to authentication-related issues.
- Minor improvements in JavaScript package collection.
- Improved detection of NixOS version number.
- Packages from Python requirements.txt files with non-deterministic version numbers are now included in the SBOM for completeness.
- Packages from JavaScript project root-level package.json files with non-deterministic version numbers are now included in the SBOM for completeness.
- C# packages with non-deterministic version numbers are now included in the SBOM for completeness.
- Fixed issue that caused a crash while processing PHP composer.lock packages with empty names and versions.
- Sbomgen now inventories PHP dev dependencies.
- Moved OS component from metadata section to components section.
- Support Chainguard namespace (Commercial version).
要約すると以下のような内容でした。
## [1.6.0] - 2025年1月27日
- サードパーティユーティリティ経由でインストールされたNode.JSランタイムの検出が改善
- コンテナスキャン中の大きなファイル抽出時のメモリ消費量を削減
- 非決定論的なバージョン番号を持つパッケージのSBOMへの追加
- Python requirements.txt
- JavaScript package.json
- C#パッケージ
- PHP composer.lock関連の不具合修正
- その他、各種検出機能の改善
この中でも大きな変更としては非決定論的なバージョン番号を持つパッケージのSBOMへの追加という部分でしょう。非決定論的なバージョンとはなんでしょうか?
非決定論的バージョンって?
例えば、Node.jsのpackage.jsonでは以下のような記述が可能です
{
"dependencies": {
"express": "4.17.1", // 固定バージョン
"lodash": "^4.17.21", // ^による範囲指定
"moment": "~2.29.1" // ~による範囲指定
}
}
上記のうち、"^"
や "~"
は以下のような意味を持ちます
^4.17.1
: 4.17.1以上5.0.0未満のバージョンを許容~4.17.1
: 4.17.1以上4.18.0未満のバージョンを許容
このように、明確な単一のバージョンではなく、範囲で指定される場合を「非決定論的バージョン」と呼ぶようです。
実際に新旧バージョンの差分を検証してみる
では実際に、新旧のSBOMジェネレータを使って差分を確認してみましょう。
SBOMジェネレータのインストール
まずは新旧バージョンのSBOM Generatorをインストールします
なお、実行環境はec2(AMD64)上のubuntu24.04です。またDockerやunzip等の各種必要なパッケージはインストール済みの状態から始めます
# 新バージョン(1.6.1)のインストール
wget https://amazon-inspector-sbomgen.s3.amazonaws.com/latest/linux/amd64/inspector-sbomgen.zip
unzip inspector-sbomgen.zip
chmod +x inspector-sbomgen-1.6.1/linux/amd64/inspector-sbomgen
# 旧バージョン(1.5.5)のインストール
wget https://amazon-inspector-sbomgen.s3.amazonaws.com/1.5.5/linux/amd64/inspector-sbomgen.zip
unzip inspector-sbomgen.zip
chmod +x inspector-sbomgen-1.5.5/linux/amd64/inspector-sbomgen
テスト用のDockerイメージ作成
非決定論的バージョンを含むパッケージ構成で検証を行うため、以下のファイルを作成します
mkdir sbomgen-test && cd sbomgen-test
Dockerfile
:
FROM node:20-slim
WORKDIR /app
COPY package.json .
RUN npm install
USER node
package.json
:
{
"name": "inspector-test",
"version": "1.0.0",
"dependencies": {
"express": "^4.17.1",
"lodash": "~4.17.21",
"moment": ">=2.29.1"
}
}
イメージをビルドします
docker build -t sbomgen-test:latest .
SBOM生成と比較
それでは、新旧バージョンでSBOMの生成とそれに基づく脆弱性の検出までやってみましょう。なお、脆弱性の検出を行うには"inspector-scan:ScanSbom"
のIAM権限が必要です。
# 1.5.5でのSBOM生成
./inspector-sbomgen-1.5.5/linux/amd64/inspector-sbomgen container \
--image node-dependency-test:latest \
--scan-sbom \
--aws-region ap-northeast-1 \
--scan-sbom-output-format cyclonedx \
--outfile 1_5_5scan.json
# 1.6.1でのSBOM生成
./inspector-sbomgen-1.6.1/linux/amd64/inspector-sbomgen container \
--image node-dependency-test:latest \
--scan-sbom \
--aws-region ap-northeast-1 \
--scan-sbom-output-format cyclonedx \
--outfile 1_6_1scan.json
生成されたSBOMから必要な部分を抽出して比較します
# パッケージ情報の抽出
jq -r '[
.components[] |
select(.name as $name | ["express", "lodash", "moment"] | contains([$name])) |
{
name,
version,
path: (.properties[] | select(.name | contains("path")).value)
}
] | sort_by(.name, .path)' 1_5_5scan.json > components_1_5_5.json
jq -r '[
.components[] |
select(.name as $name | ["express", "lodash", "moment"] | contains([$name])) |
{
name,
version,
path: (.properties[] | select(.name | contains("path")).value)
}
] | sort_by(.name, .path)' 1_6_1scan.json > components_1_6_1.json
# 差分の確認
colordiff -y components_1_5_5.json components_1_6_1.json
差分は以下のような感じでした
[ [
{ {
"name": "express", "name": "express",
"version": "4.21.2", "version": "4.21.2",
"path": "/app/node_modules/express/package.json" "path": "/app/node_modules/express/package.json"
}, },
{ {
"name": "express", "name": "express",
"version": "4.21.2", "version": "4.21.2",
"path": "/app/package-lock.json" "path": "/app/package-lock.json"
}, },
{ {
> "name": "express",
> "version": null,
> "path": "/app/package.json"
> },
> {
"name": "lodash", "name": "lodash",
"version": "4.17.21", "version": "4.17.21",
"path": "/app/node_modules/lodash/package.json" "path": "/app/node_modules/lodash/package.json"
}, },
{ {
"name": "lodash", "name": "lodash",
"version": "4.17.21", "version": "4.17.21",
"path": "/app/package-lock.json" "path": "/app/package-lock.json"
}, },
{ {
> "name": "lodash",
> "version": null,
> "path": "/app/package.json"
> },
> {
"name": "moment", "name": "moment",
"version": "2.30.1", "version": "2.30.1",
"path": "/app/node_modules/moment/package.json" "path": "/app/node_modules/moment/package.json"
}, },
{ {
"name": "moment", "name": "moment",
"version": "2.30.1", "version": "2.30.1",
"path": "/app/package-lock.json" "path": "/app/package-lock.json"
> },
> {
> "name": "moment",
> "version": null,
> "path": "/app/package.json"
} }
] ]
従来は、package-lock.json、node_modules配下からのみパッケージを抽出していましたが、それに加えて、package.jsonから抽出出来るようになっていますね。
検証結果
差分を確認すると、以下の変更が確認できました
- package.jsonに記載された非決定論的バージョンのパッケージが新たにSBOMに含まれるようになった
- これらのパッケージはversionが
null
として記録される - 実際にインストールされたバージョンは従来通り記録される
ただし、検出される脆弱性の数は新旧で変化がありませんでした
# jq '.vulnerabilities | length' 1_5_5scan.json
3
# jq '.vulnerabilities | length' 1_6_1scan.json
3
で、結局何がうれしいの?
正直なところ私は、上記により現状で何が嬉しいのかはよくわからないです。
推測にはなりますが、この変更は将来的な機能拡張への布石である可能性はあるかなと思いました。もしかしたら以下のような機能が実現可能になるかもしれませんね。またCI/CDパイプライン等で非決定論的バージョンを使っていることを検出するロジックを自前で実装するのもいいかもしれません。
リスク評価の改善
- 許容されるバージョン範囲内の既知の脆弱性を事前に把握
npm update
実行時の潜在的なリスクを予測
コンプライアンス対応
- バージョン指定ポリシーへの準拠確認
- 過度に緩いバージョン制約の検出
まとめ
以上、SBOM Generator 1.6のアップデートの検証でした。現時点では直接的な効果はあまりないかもしれませんが、今後のアップデートに期待ですね。