背景
脆弱性まとめのサイト(https://cve.autoarticles.net )を毎日更新していて、いちばん時間を取られるのが「で、うちのディストリは直ったの?」の確認でした。
NVD はアメリカの政府機関が運営している脆弱性データベースです。
そのブラウザ画面を開いて、Ubuntu のページを開いて、Red Hat を開いて、という作業を毎回やっていたのですが、そもそもこれが遅い。
どのページも JavaScript で描画されるので、テキストとして取るのも面倒でした。
今日ようやく重い腰を上げて、全部 API 側で取ることにしました。
結果として curl 5本で終わるようになったので、その5本を置いておきます。
先に用語を一つだけ。
CVE は脆弱性に付く世界共通の通し番号で、CVE-2026-53266 のような形をしています。
以下はこの番号を1つ決めて、5か所に同じ番号で聞く、という話です。
結論
下記の5本です。
すべて認証なしで叩けます(NVD だけレート制限が厳しいので後述)。
$ CVE=CVE-2026-53266
$ curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=$CVE"
$ curl -s "https://ubuntu.com/security/cves/$CVE.json"
$ curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json"
$ curl -s "https://alas.aws.amazon.com/cve/json/v1/$CVE.json"
$ curl -s "https://api.osv.dev/v1/vulns/$CVE"
それぞれ返す中身が違うので、順に見ていきます。
今日は全部 CVE-2026-53266(Linux カーネルの ebtables SNAT の境界外書き込み)で実際に叩いた結果です。
1. NVD — 点数とCWEと版レンジ
下記のとおり、CVE 番号を1つ渡して JSON を受け取ります。
$ curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-53266"
本体は vulnerabilities[0].cve の下です。
ここから取れて役に立ったのは下記でした。
-
published/lastModified/vulnStatus(今日はAnalyzed) -
metrics.cvssMetricV31[0].cvssDataのbaseScoreとvectorString -
weaknessesの CWE -
configurationsの CPE 版レンジ(どのバージョンが影響を受けるか) -
referencesのリンク(パッチのコミットなど)
metrics の中に ssvcV203 も入っていて、今日の値は exploitation: active / automatable: no / technicalImpact: total。
CVSS の点数とは別に、CISA が悪用状況をどう見ているかがここに出ます。
注意点として、NVD は API キー無しだと 30 秒あたり 5 リクエストという制限があります。
何十件も回すならキーを取るか、間隔を空ける必要があります(私のところのバッチは移動窓で待たせています)。
JSON は入れ子が深いので、必要なぶんだけ抜いています。
手元に jq を入れていない機なので、私は Node で受けています。
$ curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-53266" \
| node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{
const c=JSON.parse(s).vulnerabilities[0].cve;
const m=c.metrics.cvssMetricV31[0].cvssData;
console.log(c.id,c.vulnStatus,m.baseScore,m.vectorString)})"
CVE-2026-53266 Analyzed 8.8 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
metrics.cvssMetricV31 は配列で、提供元が複数入ることがあります。
今回は1件でしたが、複数あるときは source を見てどれを採るか決める必要があります。
2. Ubuntu — 系列ごとの状態が1発で出る
同じ CVE 番号を、今度は Ubuntu のセキュリティ API に渡します。
$ curl -s "https://ubuntu.com/security/cves/CVE-2026-53266.json"
これがいちばん素直でした。
トップレベルに status と priority があり、packages[].statuses[] に リリース名ごとの状態が入っています。
今日の linux パッケージの中身はこうでした。
trusty not-affected 3.11.0-12.19
xenial not-affected 4.4.0-2.16
bionic not-affected 4.13.0-16.19
focal needed
jammy pending 5.15.0-198.208
noble pending 6.8.0-146.146
questing ignored end of life, was needed
upstream released 7.1~rc7, 6.8.y, 6.17.y, 7.0.13
pending はビルド待ち、needed はまだ手が付いていない、ignored はサポート終了で直さない、という読み方になります。
upstream の行に上流の修正版が並ぶのが地味に便利で、ディストリを使っていない自前ビルドの人はここだけ見れば済みます。
3. Red Hat — RHSA 番号と、まだ直っていない製品
Red Hat も同じ番号で引けます。下記が実行した形です。
$ curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2026-53266.json"
こちらは2つの配列を見ます。
affected_release[] が修正済みのほうで、advisory(RHSA 番号)・package(修正が入ったパッケージのバージョン)・release_date が入っています。
今日は RHEL 8 が RHSA-2026:39083 の kernel-0:4.18.0-553.143.1.el8_10(2026-07-14)、RHEL 9 が RHSA-2026:36645 の kernel-0:5.14.0-687.23.1.el9_8(2026-07-08)でした。
package_state[] がまだ直っていないほうで、fix_state に Affected / Not affected / Will not fix が入ります。
今日は RHEL 10 の kernel と RHEL 9 の kernel-rt が Affected のまま、RHEL 6 / 7 は Not affected でした。
この2つを分けて持っているのが Red Hat の特徴で、「修正済み」だけ見ていると取りこぼすという点は覚えておきたいところです。
threat_severity と cvss3 も入っていて、今日は Important / 7.5。
NVD の 8.8 とは違います(ここは後述)。
4. Amazon Linux — ALAS 番号
Amazon Linux は ALAS という独自の番号を持っていますが、入口は CVE 番号のままで済みます。
$ curl -s "https://alas.aws.amazon.com/cve/json/v1/CVE-2026-53266.json"
affected_packages[] に、platform(amzn2 / amzn2023)・name・status・advisories[](ALAS 番号と公開日)が入ります。
今日は AL2 に ALAS2KERNEL-5.10-2026-124 と ALAS2KERNEL-5.15-2026-110、AL2023 に ALAS2023-2026-1924 など計5件が紐づいていました。
ただしこのとき status はどれも PendingFix と出ていて、アドバイザリが出ているのと表示が噛み合っていません。
この JSON だけで「まだ直っていない」と結論しないほうがよさそうです(私は ALAS のページ側を見て判断することにしました)。
なお、似た URL の https://explore.alas.aws.amazon.com/api/v1/cve/<CVE> は NoSuchKey の XML が返ってきました。
叩くなら上の alas.aws.amazon.com/cve/json/v1/ のほうです。
5. OSV — 修正コミットと、上流の fixed バージョン
最後は OSV(オープンソースの脆弱性データベース)です。下記で引きます。
$ curl -s "https://api.osv.dev/v1/vulns/CVE-2026-53266"
affected[] に、GIT 範囲(introduced と fixed がコミットハッシュ)と、ECOSYSTEM 範囲(introduced: 5.10.0 → fixed: 5.10.259 のようなバージョン)が入っています。
「どのコミットで入って、どのコミットで直ったか」が機械可読で取れるのはここだけでした。
自前でカーネルをビルドしている場合、この範囲を見るのが一番早いと思います。
点数が3つとも違う件
同じ CVE なのに、NVD 8.8 / Red Hat 7.5 / Amazon Linux 5.3 でした。
ベクタを並べると理由が見えます。
- NVD:
AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Red Hat:
AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Amazon Linux:
AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
攻撃元区分が、ローカル(AV:L)・ネットワーク(AV:N)・隣接ネットワーク(AV:A)でばらけています。
スコープも NVD だけ Changed です。
つまり CVSS は「評価者がどういう前提を置いたか」を含んだ数字で、同じ欠陥でも揃わない。
点数を一つだけ持ってきて「8.8 だから最優先」と書くのは、たぶん正確ではないです…
私のところでは NVD の値を採りつつ、記事には3つ並べて「差があること自体」を書くようにしました。
そのほうが誠実だと思ったからです。
5本を1回で回す
毎回5行打つのも面倒なので、名前を付けて保存する形にしています。
$ CVE=CVE-2026-53266
$ curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=$CVE" > nvd.json
$ curl -s "https://ubuntu.com/security/cves/$CVE.json" > ubuntu.json
$ curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json" > redhat.json
$ curl -s "https://alas.aws.amazon.com/cve/json/v1/$CVE.json" > alas.json
$ curl -s "https://api.osv.dev/v1/vulns/$CVE" > osv.json
保存だけしておいて、あとから必要なところを抜く形です。
複数の CVE を回すときは、NVD のレート制限(キー無しで30秒あたり5リクエスト)に当たらないよう、NVD への問い合わせだけ間隔を空けています。
残りの4つには、私が見た範囲では同様の制限の記載はありませんでした。
おわり
ブラウザで5サイト開いて読んでいたものが、curl 5本になりました。
それだけの話ですが、毎日やる作業なので効きます。
いちばんの収穫は、点数が3つとも違うと気づけたことでした。
ページを順番に眺めていたときは、たぶん最初に見た数字をそのまま信じていたと思います…
並べると違いが見えるので、脆弱性の優先度を決める仕事をしている人は、一度5本とも叩いてみてください。
本記事はAI補助で執筆した、個人開発の紹介記事です。