重大な脆弱性が公開され、アドバイザリが広まると、1時間もしないうちに社内チャットで誰かが尋ねます。「うちは影響を受けているのか?」この問いを有名にしたのはLog4Shellです。CVE-2021-44228は、2.0-beta9から2.15.0までのLog4j Coreに影響しました。数えきれないJava製品の依存関係ツリーの何階層も下にあったライブラリで、ほとんどのチームはそれがどこにあるのかを苦労して突き止めなければなりませんでした。
この問いは単純に聞こえますが、実際には3つの問いです。
- 脆弱なコンポーネントは、自社がビルドまたは出荷するものに含まれているか?
- 含まれている場合、自社製品で悪用され得るか?
- いつから、どのリリースに含まれているか?
多くのプロセスは最初の2つに答えます。3つ目は顧客、監査人、規制当局が次に尋ねる問いであり、事後に答えるのが最も難しい問いです。
ステップ1:コンポーネントが含まれているかを確認する
企業が答えにたどり着く方法は、おおむね成熟度の順に4つあります。
聞いて回り、検索する。 誰かがSlackに投稿し、エンジニアがリポジトリとロックファイルでパッケージ名を検索し、スプレッドシートに回答を集めます。今でも最も一般的な方法です。時間がかかり、誰が回答するかに左右され、ファイルで宣言されていないもの、つまり依存関係の依存関係、ベンダリングされたライブラリ、ベースイメージ、ビルド中にインストールされるツールを見落とします。
スキャナーのダッシュボードを確認する。 依存関係スキャナーは数時間以内にリポジトリごとにCVEを検出します。より速い方法ですが、スキャナーが報告するのは今目の前にあるコード、通常はデフォルトブランチについてです。顧客がどのリリースを使っているかや、3か月前のビルドが実際に何を取り込んだかはわかりません。
SBOMのインベントリに問い合わせる。 リリースごとにソフトウェア部品表を保持しているチームは、それらすべてに対して1つの問いを投げかけられます。このパッケージの影響を受けるバージョンを含むのは、どの製品のどのバージョンか。リポジトリ内のソフトウェアだけでなく、出荷したソフトウェアについて答えられる最初の方法です。
継続的に照合する。 SBOMを脆弱性データと照らして監視していれば、影響を受ける製品の一覧は誰かが尋ねる前に存在します。チャットのスレッドは問いではなく、答えから始まります。
どの方法の質も、インベントリに実際に何が含まれているかで決まります。よくある盲点は次のとおりです。
- 推移的依存関係。 脆弱なパッケージが自分で追加したものであることはまれです。3階層、4階層下から入り込みます。
- マニフェストが宣言していないもの。 ビルドスクリプトがインストールするパッケージ、
npxツール、Dockerfileのステップ、復元されたキャッシュ、ベンダリングされたCやC++のコードです。 - 古いリリース。 もうビルドできないブランチは再スキャンできませんが、そこからビルドされた製品はまだ現場で使われているかもしれません。
ステップ2:問題になるかを判断する
コンポーネントが含まれていても、実際のリスクとは限りません。そこで次のステップはトリアージです。
- バージョンと設定。 バージョンは影響を受ける範囲に正確に収まっているか。脆弱な機能はコンパイルに含まれ、有効になっているか。
- 到達可能性。 コードは脆弱な関数をそもそも呼び出しているか。
- 露出。 コンポーネントはネットワークや信頼できない入力から到達可能か、それともビルド時にしか使われないか。
- 緩和策。 悪用を阻止するサンドボックス、ネットワーク制限、設定はあるか。
- 悪用のシグナル。 CVSSは深刻度を示し、EPSSはCVEが今後30日以内に悪用される確率を推定し、CISAのKnown Exploited Vulnerabilitiesカタログはすでに実際に悪用されているものを掲載しています。これらを組み合わせて、何を先に調べるかを決めます。
ステップ3:判断を記録する
結果は製品とバージョンごとに記録され、VEX(Vulnerability Exploitability eXchange)ステートメントとして記録されることが増えています。CISAのVEXの最小要件は、not affected(影響なし)、affected(影響あり)、fixed(修正済み)、under investigation(調査中)の4つのステータスを定義しています。「影響なし」のステートメントには、脆弱なコードが存在しない、攻撃者が到達できないなど、その理由を記載する必要があります。
その記録は、その後のすべての作業の基になります。修正とそれを含むリリース、顧客向けのセキュリティアドバイザリ、規制当局が求める報告です。たとえばEUのCyber Resilience Actでは、メーカーは自社製品で積極的に悪用されている脆弱性を認識してから24時間以内に早期警告を送らなければなりません。
ステップ4:影響期間を特定する
「影響はあるか?」には、見落とされがちな後半があります。どれだけの期間影響を受けていたのか、です。
脆弱性は、CVEが公開されるずっと前から存在していました。Log4ShellはLog4jの2.0-beta9から存在しており、それは誰かが公表する何年も前にリリースされていました。影響期間は、ビルドが初めて脆弱なバージョンを取り込んだ日に始まり、それを含む最後のビルドが置き換えられた日に終わります。この期間は次のために必要です。
- 最新のリリースだけでなく、顧客が使っているどのリリースが影響を受けるかを伝える
- 脆弱性が悪用された可能性がある場合に、インシデント調査の対象期間を正しく絞り込む
- 問題がいつ製品に入り込み、修正がいつ出荷されたかを監査人や規制当局に示す
今日のコードをスキャンしても、それはわかりません。現在のロックファイルが示すのはリポジトリが今求めているものであり、過去の各ビルドがインストールしたものではありません。信頼できる唯一の情報源は、すべてのビルドについて、実行中に取得し、その後も保持した記録です。
CRACIによる答え方
CRACIはGitHub Actionsのジョブを自社のランナーで実行し、スクリプトがインストールしたものやキャッシュから復元されたものを含め、各ビルドが実際に取り込んだすべてのパッケージを、直接・推移的を問わず記録します。各ビルドのSBOMは保持されるため、CVEが公開された時点で履歴はすでにそろっています。
新しいCVEが公開されたとき、答えはすでにあります。過去のすべてのビルドとそのSBOM、そのうちどれが直接または推移的に脆弱な依存関係を含んでいたか、そして影響を受けていた期間です。スプレッドシートも、再スキャンも、ロックファイルからの再構成も必要ありません。それを含んでいた最初のビルドと、それを取り除いたビルドから、保持期間の範囲内(デフォルトで180日、Enterpriseではカスタムの保持期間)で影響期間がわかります。
影響が判明したら、ポリシーゲートでこのCVEを含むビルドをブロックできます。そのため、後の依存関係の更新や復元されたキャッシュによって、脆弱なバージョンが気付かないうちにリリースに戻ってくることはありません。
そこから先のプロセスにも、確かな土台ができます。
- CRACIはSBOMを継続的に監視するため、誰かが尋ねなくても新しいCVEがビルドと照合されます。
- セキュリティチームは検出結果をトリアージして修正を担当するチームに送り、CRACIは結果を記録するためのVEXをサポートします。
- CRACIのインベントリは、どのソフトウェアバージョンがどの製品にデプロイされているかを示します。
- CRAについては、CRACIが早期警告、通知、最終報告の内容を準備し、貴社の担当者がSingle Reporting Platformを通じて提出します。
答えがわかったら、顧客に伝えましょう。サプライチェーン攻撃後に顧客へどう回答するかでは、第一報と各結果のテンプレートを紹介しています。問い合わせが数百件単位で届くなら、PSIRTをスケールさせる方法をご覧ください。
デモを予約して、お客様のリポジトリの1つのビルド履歴をご覧ください。
