0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zammad の CVE-2026-102489 は、NVD の版範囲だけで判定すると 6.5.4 を見落とす

0
Posted at

背景

私は脆弱性情報をまとめるサイトを個人で運用しています。この記事で扱う CVE の個別ページもあります。

昨日(2026-10-02)、問い合わせ管理ツール Zammad の CVE が2件まとめて KEV に載りました。
自分で Zammad を立てたことはないのですが、OSS のヘルプデスクとして社内に置いている所は多い気がします。
版範囲を眺めていたら出典ごとに少しずつ違っていて、機械で判定すると取りこぼす版があったので、手を動かして確かめておきます。

2件の CVE は何か

CVE は、公開された脆弱性に振られる世界共通の識別番号だ。
KEV は、アメリカの CISA が「実際に悪用されている」と確認した脆弱性の一覧です。
今回の2件は 2026-10-02 に KEV へ収載され、米連邦機関向けの是正期限は 2026-10-05 になっています。

1件目の CVE-2026-102489 は、セッション固定(CWE-384)の脆弱性である。
セッション固定というのは、攻撃者が用意したセッションを利用者に使わせて、ログイン後のセッションを乗っ取る攻撃のことです。
これが、Zammad の実行ユーザー(zammad)権限でのリモートコード実行につながる。

2件目の CVE-2026-102490 は、権限管理の不備(CWE-269)で、ローカルの zammad ユーザーが root に昇格できる。
KEV の説明には、この2件は連鎖させられると書かれています。
つまり1件目で zammad ユーザーとして入り、2件目で root まで上がる、という組み合わせです。

NVD は、アメリカの NIST が運営する脆弱性データベースです。
NVD の評価は2件とも CVSS 3.1 で 9.8 になっている。
CVSS は脆弱性の深刻度を 0〜10 で表す指標で、9.0 以上が Critical です。

一次情報は下記です。

https://nvd.nist.gov/vuln/detail/CVE-2026-102489
https://nvd.nist.gov/vuln/detail/CVE-2026-102490
https://csirt.divd.nl/cases/DIVD-2026-00015/
https://community.zammad.org/t/take-care-local-privilege-escalation-cve-2026-102490-is-reported-as-being-actively-exploited/21297

DIVD はオランダの脆弱性調査の非営利団体で、今回の発見者です。
DIVD の記載によると、2026-09-21 に自分たちの Zammad がこの穴で侵害され、2026-09-24 に Zammad へ報告しています。

版範囲が出典ごとに違う

CVE-2026-102489 の版範囲は、私が読んだ範囲で3通りの書き方がありました。

  1. NVD の説明文と DIVD: 6.3.0 から 6.5.4 が該当。7.0.0 から 7.1.3 にも存在するが、環境の条件で悪用できない
  2. NVD の CPE: 6.3.0 以上 6.5.4 未満、と 7.0.0 以上 7.1.3 以下
  3. Zammad の声明: 悪用できるのは 6.5 以前で、7.0 以降は影響を受けない

CPE は、製品と版を機械で照合するための NVD の書式だ。
NVD の API から CPE を引いて「該当/非該当」を出す、という作りの判定は多いと思います。

気になったのは2つ目の「6.5.4 未満」です。
GitHub のタグを見ると、6.5 系の最後の版は 6.5.4 でした。
説明文は「6.5.4 まで」なのに、CPE は 6.5.4 を含まない。
この食い違いのせいで、6.5 系を最後まで上げて止めている環境ほど、CPE だけの判定では非該当に落ちます。

CVE-2026-102490 のほうは、NVD の CPE が「1.5.0 以上 7.1.0 未満」と「7.1.0-alpha」で、Zammad の声明の「1.5 から 7.1.0-alpha」と一致しています。
ただ Zammad の声明は、対策として 7.2.0 への更新を勧めています。

版ごとに並べて確かめる

文字で読んでいると端の扱いを取り違えそうだったので、出典ごとの範囲をそのままコードにして、版を当ててみました。
入力は Zammad の版の文字列(6.5.4 や 7.1.0-alpha の形)です。
自分の環境の版は、管理画面かパッケージ管理の表示で確かめた値を入れる想定です。
alpha は同じ番号の正式版より前に並べています。

// Zammad の版を、出典ごとの「影響範囲」に当てて比べる
function parse(v) {
  const m = /^(\d+)\.(\d+)\.(\d+)(-alpha)?$/.exec(v);
  if (!m) throw new Error('形式が違います: ' + v);
  // alpha は同じ番号の正式版より前に並べる
  return [Number(m[1]), Number(m[2]), Number(m[3]), m[4] ? 0 : 1];
}
function cmp(a, b) {
  const x = parse(a), y = parse(b);
  for (let i = 0; i < 4; i++) if (x[i] !== y[i]) return x[i] - y[i];
  return 0;
}
const between = (v, lo, hi, hiInclusive) =>
  cmp(v, lo) >= 0 && (hiInclusive ? cmp(v, hi) <= 0 : cmp(v, hi) < 0);

// CVE-2026-102489(セッション乗っ取り → zammad ユーザーで RCE)
const rce = {
  // NVD の CPE: 6.3.0 以上 6.5.4 未満 / 7.0.0 以上 7.1.3 以下
  nvdCpe: (v) => between(v, '6.3.0', '6.5.4', false) || between(v, '7.0.0', '7.1.3', true),
  // NVD・DIVD の説明文: 6.3.0 to 6.5.4 が悪用可能(7.0.0〜7.1.3 は「存在するが悪用不可」)
  text: (v) => between(v, '6.3.0', '6.5.4', true),
  // Zammad の声明: 悪用できるのは 6.5 以前、7.0 以降は影響なし
  vendor: (v) => cmp(v, '7.0.0-alpha') < 0,
};
// CVE-2026-102490(zammad ユーザー → root)
const lpe = {
  // NVD の CPE: 1.5.0 以上 7.1.0 未満 と 7.1.0-alpha
  nvdCpe: (v) => between(v, '1.5.0', '7.1.0', false),
  // Zammad の推奨は 7.2.0 への更新。ここでは 7.2.0 未満を更新対象として扱う
  vendor: (v) => cmp(v, '7.2.0') < 0,
};
const mark = (b) => (b ? '該当' : '-   ');
console.log('version      | 102489 CPE 説明文 声明 | 102490 CPE 7.2.0未満');
for (const v of ['6.2.0', '6.5.3', '6.5.4', '7.0.3', '7.1.0-alpha', '7.1.3', '7.2.0']) {
  console.log(
    v.padEnd(12), '|', mark(rce.nvdCpe(v)), mark(rce.text(v)), mark(rce.vendor(v)),
    '|', mark(lpe.nvdCpe(v)), mark(lpe.vendor(v)),
  );
}

Node.js v24.11.1 で実行した結果は下記です。

$ node zammad.js
version      | 102489 CPE 説明文 声明 | 102490 CPE 7.2.0未満
6.2.0        | -    -    該当 | 該当 該当
6.5.3        | 該当 該当 該当 | 該当 該当
6.5.4        | -    該当 該当 | 該当 該当
7.0.3        | 該当 -    -    | 該当 該当
7.1.0-alpha  | 該当 -    -    | 該当 該当
7.1.3        | 該当 -    -    | -    該当
7.2.0        | -    -    -    | -    -

6.5.4 の行で、CVE-2026-102489 が CPE だけ非該当になっているのがわかると思います。
逆に 7.0.3 や 7.1.3 は、CPE では該当なのに説明文と声明では「悪用できない」側です。
CPE は「コードが存在する」範囲を、説明文と声明は「悪用できる」範囲を書いている、と読むのがよさそうです。
6.2.0 の行が声明だけ該当なのは、声明が「6.5 以前」としか書いておらず、私のコードが下限を置いていないからです(6.3.0 未満が危ないという意味ではありません)。

7.1.3 の行も見ておきます。
CVE-2026-102490 は CPE だと 7.1.3 が非該当ですが、Zammad が勧めているのは 7.2.0 です。
7.1.x が直っているのかどうかは、私が読んだ一次情報からは読み取れませんでした。

どの範囲で判定するか

私は、CPE だけで判定せず、説明文とベンダーの修正版のうち広いほうを採ることにしました。
理由は、取りこぼしと誤検知の重さが釣り合っていないからです。
誤検知(直っている版を「要更新」と言う)の損は、更新の手間が1回増えるだけ。
取りこぼし(6.5.4 を「非該当」と言う)の損は、悪用が確認済みの穴を開けたまま放置することです。
この件は DIVD 自身が実際に侵害されていて、しかも2件を連鎖させると root まで届く。
なので Zammad では、7.2.0 未満はすべて更新対象として扱います。

もう1つ、DIVD はログから侵害の痕跡を探すスクリプトも公開しています。
収載より前から悪用されていた件なので、更新だけでなくログの確認もしたほうがいい気がします…。

NVD の CPE で機械判定している人は、範囲の端の版(今回なら 6.5.4)を説明文と見比べ、食い違ったら広いほうかベンダーの修正版を閾値にしてください。


本記事はAI補助で執筆した、個人開発の紹介記事です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?