Log4Shellが公表された2021年12月、多くの企業が最初にぶつかったのは「直すのが難しい」ではなかった。そもそも自社の製品にlog4jが入っているのか分からない、だった。持ち物の一覧がなければ、危ないと言われても照合のしようがない。SBOM(Software Bill of Materials)は、この一覧をつくる仕組みだ。
部品表という発想#
BOM(Bill of Materials)は製造業の言葉で、製品を構成する部品の一覧を指す。自動車のリコールが成立するのは、どの車体にどのロットの部品が付いたかを追えるからだ。
ソフトウェアには長いあいだ、これがなかった。手元のアプリケーションには何百というパッケージが入る。そのほとんどは依存の依存として自動で降ってきたもので、開発した本人でさえ全部は把握していない。何を積んだか分からないまま出荷している、という状態が普通にあった。
SBOMは、その中身を機械可読な形で書き出したものだ。何が、どの版で、どこから来て、何に依存しているか。それだけを持つ。
SPDXとCycloneDX#
代表的な形式は二つある。生まれた動機が違う。
SPDXはLinux Foundationが育てた形式で、出自はライセンス管理にある。オープンソースを製品に組み込むとき、どのライセンスが混ざっているかを追う必要があった。2021年にISO/IEC 5962:2021として国際規格になっている。
CycloneDXはOWASPのプロジェクトだ。最初からセキュリティを向いていて、脆弱性情報やVEXとの連携が設計に入っている。
どちらを選ぶかは、何に使うかで決まる。ライセンス監査まで含めるならSPDX、脆弱性の照合が主目的ならCycloneDXが扱いやすい。両方を出力できるツールも多い。
何が書かれているか#
形式は違っても、中心にある情報は近い。
- コンポーネント名と版 —
log4j-coreの2.14.1のように特定できる粒度で - 識別子 —
purl(Package URL)のような、エコシステムを含めた一意の名前 - ハッシュ — 本当にその中身かを確かめるため
- ライセンス — 法務側が使う
- 依存関係 — どの部品がどの部品を必要としているか
なかでもpurlが効く。エコシステムと名前と版を、一つの文字列にまとめる書き方だ。
pkg:npm/lodash@4.17.21
pkg:pypi/requests@2.31.0
pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1
同名でもnpmとPyPIは別物だ。この区別がないまま名前だけで突き合わせると、無関係な脆弱性を拾う。逆に、エコシステムの表記が揺れていれば該当を見落とす。地味だが、照合の成否はここで決まる。
深さが問題になる#
SBOMを出したから安心、とはならない。どこまで深く書けているかで価値が変わる。
直接インストールしたパッケージだけを並べたSBOMは、実際の脆弱性の多くが依存の依存として入ってきたものから出る以上、ほとんど役に立たない。Log4Shellのときも、log4jを直接指定していた組織は少数派だった。
依存ツリー全体を辿れているかは、生成の方法で決まる。
ビルド時に取るのが正確だ。実際に解決された版が確定しているので、ロックファイルと同じ情報が得られる。
できあがったものから推測する方法もある。コンテナイメージを走査してパッケージを見つけ出す形で、手軽なかわりに、静的にリンクされたものやパッケージ管理を経ずに置かれたファイルは落ちる。
ソースコードから読む方法は、その中間だ。宣言を読むだけなので速いが、版が固定されていなければ実際に入るものと食い違う。package.jsonの^1.2.0という記述からは、入る版が決まらない。
三つのうちどれを選ぶかは、何を保証したいかによる。出荷物の中身を証明したいならビルド時、既に動いているものを調べたいなら走査、設計段階の見通しならソースコードになる。
脆弱性データベースと組み合わせる#
SBOM単体では何も判定しない。判定は、脆弱性データベースと突き合わせて初めて出る。
SBOMが「何を持っているか」、OSVやGHSAが「何が壊れているか」。片方だけでは何も出ないが、この二つを突き合わせると「自分に該当するものはどれか」がようやく決まる。
だからSBOMの品質は、そのまま照合の精度になる。版が曖昧なら該当判定も曖昧になるし、間接依存が抜けていればそこは丸ごと見えない。
AIを積むと、部品表の対象が広がる#
モデルを組み込んだシステムでは、SBOMの守備範囲が足りなくなる。
動いているのはコードだけではない。事前学習モデル、微調整の重み、埋め込みの索引、プロンプトの雛形。どれも外から持ち込まれて差し替わっていくのに、従来のパッケージ管理には乗らない。
そこでAI BOM(AI Bill of Materials)という考え方が出てきた。モデルの出所、版、学習データの由来、評価の結果までを部品として記録する。CycloneDXは機械学習向けの記述に対応している。
考え方は同じだ。外から持ち込んだものを、持ち込んだと書き残す。 対象がライブラリからモデルへ広がっただけになる。
制度がSBOMを求めはじめた#
技術的な便利さだけでなく、外から要求されるようになってきた。
アメリカでは2021年の大統領令14028が、連邦政府に納入するソフトウェアへのSBOM添付を求めた。調達の条件になった時点で、事実上の必須になる。
EUのサイバーレジリエンス法(CRA)も、デジタル製品にコンポーネントの把握を求める。適用は段階的だが、向いている方向は同じだ。
日本でも、経済産業省がSBOM導入の手引を出している。まだ義務ではないが、取引先から求められる場面は増えている。
受け取る側が、何を求めるか#
自分で作っていないソフトウェアを社内に入れるとき、SBOMは調達の道具になる。
「セキュアに作ってください」では何も決まらないが、「納品物にSBOMを付けてください」なら確かめられる。しかも受け取ったあと、新しい脆弱性が公表されるたびに自分で照合できる。開発会社に問い合わせて返事を待つ必要がなくなる。
求めるときは、三点を書いておくと揉めにくい。
- 形式と版 — SPDXかCycloneDXか、どの版か
- 深さ — 直接依存だけか、間接依存まで含むか
- 更新の約束 — リリースのたびに出し直すのか、年に一度なのか
三番目が抜けやすい。初回だけ受け取っても、次のリリースで中身が変わればその一覧は使えなくなるので、いつ出し直すかまで含めて合意しておく必要がある。
過信しないための注意#
SBOMは、ある時点の写しにすぎない。 ビルドのたびに中身は変わる。古いSBOMを見て「入っていない」と判断すると外れる。生成を自動化して、成果物と一緒に配るのが前提になる。
書いてあることの正しさは、生成器の性能で決まる。 同じイメージから複数のツールでSBOMを取ると結果が一致しないことがあり、取りこぼしも余計な検出も起きる。
一覧があることと、安全であることは違う。 SBOMは「何を持っているか」に答えるだけだ。「危ないか」には答えない。そこは到達可能性の判断や、VEXのような仕組みが受け持つ。
配り方も決めておく必要がある。 作っただけで手元に置いていては、取引先から求められたときに出せない。成果物と同じ場所に置き、版ごとに残す。署名を添えて改ざんを検出できるようにする組織もある。
まとめ#
SBOMが解決したのは、脆弱性そのものではない。問いに答えられる状態をつくったことの方が大きい。
「うちにlog4jは入っていますか」に、調べればすぐ答えられる。この一点が、事故が起きてからの動きを変える。持ち物が分かっていない状態では、対処の前に調査から始めることになる。
外から出所の分からない部品を取り込んで動かす場面が増えるほど、何を取り込んだかを書き残しておく価値は上がっていく。