VEX 人が下した判断を、機械が運べる形にする

SBOMを出し、脆弱性データベースと突き合わせると、警告が大量に出ます。数百件になることも珍しくありません。そしてそのほとんどは、実際には影響しません。使っていない関数の脆弱性、到達できない経路の脆弱性、既に別の手当てで塞がっている脆弱性。これを一件ずつ人が調べ直す状態を終わらせるための形式が、VEX(Vulnerability Exploitability eXchange)です。

「該当する」と「危ない」の隙間

照合が出すのは、あくまで版の一致です。手元にlog4j-core 2.14.1が入っていて、その版にCVE-2021-44228が該当する。ここまでは機械が判定できます。

判定できないのはその先です。その脆弱性のあるコードを、自分は実際に呼んでいるのか。 呼んでいたとして、攻撃者が入力を制御できる経路にあるのか。

答えは製品ごとに違います。同じライブラリを積んでいても、使い方が違えば結論は変わります。この判断は、その製品を作った人にしかできません。

VEXは、その判断を機械可読な形で外に出す仕組みです。

四つの状態

VEXの中心は単純です。ある製品とある脆弱性の組に対して、状態を一つ付けます。

  • not_affected:影響しない
  • affected:影響する
  • fixed:修正済み
  • under_investigation:調査中

under_investigationがあるのが実務的なところです。公表直後は結論が出ていません。何も言わないより、調べていると言うほうが受け取る側は動きやすくなります。

そしてnot_affectedと言うときは、理由を添えます。ここがVEXの肝になります。

理由を分類する

「影響しません」だけでは、受け取った側が信じる根拠を持てません。VEXは理由を決められた区分から選ばせます。

  • component_not_present:その部品自体が入っていない
  • vulnerable_code_not_present:部品は入っているが、問題のコードは含まれない
  • vulnerable_code_not_in_execute_path:含まれるが、実行経路に乗らない
  • vulnerable_code_cannot_be_controlled_by_adversary:経路に乗るが、攻撃者が制御できない
  • inline_mitigations_already_exist:既に別の手当てで塞いである

区分になっていることに意味があります。自由記述だと読み手が毎回解釈することになりますが、決まった値なら機械が処理できます。「影響しない」と主張する製品を、理由の種類ごとに絞り込めます。

inline_mitigations_already_existだけは注意が要ります。手当てが外れれば影響するようになるので、その手当て自体を管理下に置いておく必要があります。

三つの書き方

形式は一つに定まっていません。用途の違う三つが並立しています。

CSAFはOASISの標準で、そのなかにVEXのプロファイルがあります。もともとはベンダーがセキュリティ勧告を配るための形式で、VEXはその一部として位置づけられます。重厚なぶん、表現力があります。

OpenVEXはOpenSSFの仕様で、必要最小限に絞ってあります。一つの文書に一つの主張、という単純さを保っています。生成も解釈も軽く済みます。

CycloneDXはSBOMの形式そのものにVEXを持てます。部品表と影響有無を同じ文書に置けるので、扱いが一体になります。

どれを選ぶかは、誰に渡すかで決まります。既にCSAFで勧告を配っているならCSAF、SBOMと一緒に配るならCycloneDX、自動化の部品として軽く扱いたいならOpenVEXが向きます。

実際の中身

OpenVEXの文書は、驚くほど短いものです。一つの主張は、対象と脆弱性と状態と理由だけで書けます。

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "author": "Example Corp",
  "timestamp": "2026-09-06T09:00:00Z",
  "statements": [
    {
      "vulnerability": { "name": "CVE-2021-44228" },
      "products": [{ "@id": "pkg:maven/com.example/app@1.4.0" }],
      "status": "not_affected",
      "justification": "vulnerable_code_not_in_execute_path"
    }
  ]
}

製品の指定にpurlを使っているのが要点です。SBOMと同じ識別子なので、部品表とVEXが同じ名前で突き合わさります。ここが揃っていないと、人手で対応表を作る羽目になります。

timestampも効きます。いつ時点の判断かが分かるので、その後に状況が変わったかを追えます。

誰が書き、誰が読むか

VEXは、上流から下流へ流れます。

製品を作った側が書きます。ライブラリの作者、アプリケーションの開発会社、機器のベンダー。自分の製品について、その脆弱性が効くかどうかを宣言します。

受け取った側が読みます。照合で出た警告に対して、供給元のVEXがあれば「調べ済み」として扱えます。なければ自分で調べます。

この流れが成立すると、同じ調査が組織の数だけ繰り返されなくなります。 一社が一度判断すれば、下流の全員がその結果を使えます。VEXが解こうとしているのは、技術の問題ではなく、この重複の問題です。

警告が減るとは限りません

VEXを導入する動機は「警告を減らしたい」であることが多いものです。ただ、減り方には偏りがあります。

減るのは、供給元が整備している範囲だけです。 大手のベンダー製品やよく使われるOSSは、VEXが出てくる可能性があります。小さな依存や社内製のものは出てきません。

そして依存の数でいえば、後者のほうが圧倒的に多くなります。全体の警告数が劇的に減る、という期待は外れます。

効くのはむしろ質のほうです。手を付けるべきものが、手を付けなくていいものに埋もれなくなります。 数が減らなくても、順序が付けば動けます。

自社が供給する側なら、話は逆になります。VEXを出すことで、顧客からの問い合わせが減ります。「御社の製品にこの脆弱性は影響しますか」という質問に、毎回個別に答えなくてよくなります。

過信しないための注意

VEXは主張であって、証明ではありません。 書いたのは供給元で、その内容を第三者が検証しているわけではありません。誰の主張かを見て、信用の度合いを決める必要があります。

古くなります。 製品の版が変われば、実行経路も変わります。以前not_affectedだったものが、次の版では該当することがあります。VEXは製品の版に紐づくものとして扱ってください。

ないことは、安全を意味しません。 供給元がVEXを出していないのは、影響しないからではなく、単に出していないからです。空白をnot_affectedと読み替えてはいけません。

全件は出てきません。 現実には、VEXを整備しているのは一部の供給元に限られます。届かない分は、結局こちらで判断することになります。

状態の意味を取り違えないでください。 fixedは修正済みの版があるという意味であって、こちらが更新したという意味ではありません。更新して初めて、自分にとっての解決になります。

どこから手を付けるか

自社で扱うなら、受け取る側と出す側で始め方が違います。

受け取る側は、まず供給元がVEXを出しているかを確かめるところから始まります。出ていれば取り込み、出ていなければ従来どおり自分で判断します。取り込みに対応した照合ツールも増えてきました。

出す側は、全部を書こうとしないほうが続きます。現実的なのは、問い合わせが多い脆弱性から順に書くやり方です。同じ質問が三度来たなら、それは書くべき一件になります。

書式は最初から凝らなくて構いません。OpenVEXなら数行で始められるので、運用に乗せてから形式を検討しても遅くありません。続かない仕組みを作るより、粗くても回るほうが価値が出ます。

まとめ

SBOMが「何を持っているか」、脆弱性データベースが「何が壊れているか」、VEXが「それは自分に効くか」。三つで一組になります。

前の二つは機械が処理できますが、三つ目だけは人の判断が要ります。VEXがやったのは判断の自動化ではなく、人が下した判断を、機械が運べる形に変えたことのほうです。

判断そのものは減りません。同じ判断を何度も繰り返すことが減ります。警告の数が増え続ける以上、効いてくるのはこちらの効率になります。自社の運用を見直すなら、脆弱性の警告に対して「影響しないと判断した理由」がどこに残っているかを確かめてください。担当者の記憶や個別のメールにしか残っていなければ、同じ調査が次の公表時にもう一度発生します。

まずはお気軽にご相談ください。目的や課題を丁寧にヒアリングし、
ご予算や納期に合わせた最適なご提案をいたします。

まずはお気軽にご相談ください。
目的や課題を丁寧にヒアリングし、
ご予算や納期に合わせた最適な
ご提案をいたします。

無料相談はこちら