Node.jsに脆弱性10件。依存3つの静的サイトを点検したら、別に10件出てきた
2026年10月21日、Node.js のセキュリティリリースが出ました。10件のCVEで、うち1件はリモートコード実行につながります。
このサイトも Node.js でビルドしています。そこで点検したのですが、出てきたのは本体の10件とはまったく別の、依存関係の脆弱性10件でした。数が同じなのは偶然です。そして、この2つを混同したまま対応すると片方が残ります。
点検から修正までの実際の記録を書きます。数字はすべてこのサイトの実測値です。
まず、Node.js 本体の10件
公式(nodejs.org)の発表内容です。2026年10月22日に確認しました。
修正版:v26.12.1 / v24.22.1(最新LTS)/ v22.23.4
| CVE | 内容 | 深刻度 |
|---|---|---|
| CVE-2026-111497 | Brotli デコーダの境界外書き込み。RCEにつながる | High |
| CVE-2026-105482 | dns.resolve が NUL を含む名前を切り詰める |
High |
| CVE-2026-105483 | 全角数字のIPでTLS証明書のホスト名検証を回避できる | High |
| CVE-2026-106069 | ホスト名が緩くIPに解決される場合にTLS検証を回避できる | High |
| CVE-2026-105481 | keep-alive で、リクエスト送信前に書かれた応答を処理する | Medium |
| CVE-2026-106072 | 非正規形式のIPv4ホスト名で証明書検証が不適切になる | Medium |
| CVE-2026-106074 | randomUUID() / randomInt() のエントロピーがスナップショットに保存され、毎回同じ値を返す |
Medium |
| CVE-2026-106070 | ZipFile がヘッダ検証失敗後に攻撃者制御のバイトを返す | Low |
| CVE-2026-106071 | Permission Model のワイルドカード検索で権限が過剰付与される | Low |
| CVE-2026-106073 | fs.realpathSync で Permission Model を回避できる |
Low |
あわせて c-ares、OpenSSL、SQLite、Undici が更新され、eMudhra 中間CAの侵害に対応したCA証明書の更新も含まれています。
サポートが終了したバージョンも影響を受けますが、修正は出ません。
次に、自分のサイトを数えた
ここからが本題です。
このサイトの package.json に書いてある依存は、3つだけです。
"dependencies": {
"@astrojs/rss": "^4.0.19",
"@astrojs/sitemap": "^3.7.3",
"astro": "^7.2.4"
}
意図的に最小限にしてあります。それでも npm ci のあとに数えると、こうなりました。
| 項目 | 実測 |
|---|---|
package.json に書いた依存 |
3 |
npm ci が報告したパッケージ数 |
224 |
node_modules のサイズ |
228 MB |
公開される dist のサイズ |
1.2 MB |
3つ書いたら224個入ってきます。**自分で選んだのは1.3%**です。
数え方には注意が要ります。ls node_modules | wc -l では176しか出ません。
@astrojs/... のようにスコープ付きのパッケージが1ディレクトリにまとまるためです。
npm ci や npm audit が出力する「audited ◯◯ packages」が一番確実です。
npm audit を走らせた結果
10 vulnerabilities (1 moderate, 8 high, 1 critical)
内訳です。
| 深刻度 | パッケージ | 直接依存か | 内容 |
|---|---|---|---|
| critical | astro | はい | AVIF画像最適化経由のRCE |
| high | devalue | いいえ | 共有メモリをシリアライズする |
| high | http-cache-semantics | いいえ | max-stale 処理でキャッシュが漏れる |
| high | js-yaml | いいえ | マージキーでCPUを消費する |
| high | sharp | いいえ | libheif の脆弱性 |
| high | source-map-js | いいえ | イベントループのDoS |
| high | svgo | いいえ | removeScripts が実行可能リンクを通す |
| high | undici | いいえ | WebSocket の未処理エラーでDoS |
| high | vite | いいえ | launch-editor 経由の任意コマンド実行ほか |
| moderate | smol-toml | いいえ | parse() が二次時間になる |
critical が直接依存の astro にありました。 気づいていませんでした。
本体の10件と、auditの10件は別物です
ここが混同されやすい点です。
| Node.js 本体の10件 | npm audit の10件 |
|
|---|---|---|
| 対象 | ランタイムそのもの | 依存ツリーのパッケージ |
| 直し方 | Node のバージョンを上げる | npm audit fix など |
| 気づき方 | ニュースで知る | 自分で走らせないと分からない |
ニュースを見て Node を上げただけでは、npm audit 側は1件も直りません。逆もまた同じです。両方やる必要があります。
静的サイトでは、効く範囲が違います
本体の10件を見ると、TLS証明書のホスト名検証、keep-alive の応答処理、DNS解決。どれも「リクエストを処理するNode」が前提です。
このサイトの Node は、npm ci して astro build を実行し、生成した HTML を置いて終わりです。リクエストは一切処理しません。配信は CDN が静的ファイルを返すだけで、そこに Node はいません。
同じことが npm audit の側にも言えます。vite の脆弱性は開発サーバーのもので、本番の成果物には乗りません。実際、dist の 1.2MB を調べても vite の痕跡はありませんでした。
では無視していいのか
いいえ。理由が3つあります。
1. ビルド環境そのものが攻撃対象です。 ビルドは、あなたのリポジトリとデプロイ先の認証情報が揃っている場所で動きます。ここで任意コードが実行されると、生成物に何を混ぜることもできます。配信物に乗らないことと、安全であることは別です。
2. 「踏んでいない」の確認コストが高い。 当サイトの critical は AVIF 画像最適化の経路でした。確かに astro:assets も <Image> も使っておらず、画像はすべて WebP なので踏んでいません。ですが、それを毎回確認するより更新するほうが速くて確実です。
3. 構成はいつか変わります。 今日使っていない機能を、来月使うかもしれません。
直した結果
npm audit fix
| 前 | 後 | |
|---|---|---|
| 脆弱性 | 10件 | 0件 |
| astro | 7.2.4 | 7.4.1 |
| パッケージ数 | 224 | 217 |
node_modules |
228 MB | 232 MB |
パッケージは7個減りましたが、容量は4MB増えています。 セキュリティ更新で軽くなるとは限りません。 「依存が減ったか」と「容量が減ったか」は別の話なので、片方だけ見て判断しないでください。
^7.2.4 の範囲内の更新だったので、互換性の問題は出ませんでした。更新後にユニットテスト114件、33ページのビルド、全32URLの表示確認まで通しています。
更新したら必ず確認してください。 audit fix は依存を書き換えるので、通ることを確かめずに本番へ出すのは危険です。
.nvmrc の書き方で結果が変わります
最後に、あまり指摘されていない点を。
ホスティングでビルドする場合、使われる Node のバージョンは .nvmrc や .node-version で決まります。このサイトの .nvmrc はこうです。
22
マイナー以下を書いていません。そのため、ホスティング側が持っている 22系の最新が使われます。今回のような修正版が出れば、次のビルドで自動的に拾います。
一方、こう書いてある場合は違います。
22.22.0
固定したバージョンが使われ続けます。 修正版が出ても、この数字を書き換えるまで古い Node でビルドされます。再現性のために固定するのは正しい作法ですが、固定したなら更新する責任が発生します。 書いて忘れるのが一番よくありません。
自分がどちらなのかは、リポジトリのルートを見れば分かります。
自分のサイトで確かめる手順
# 1. いま動いている Node を見る
node -v
# 2. 依存の実数を数える(3つのつもりが何個あるか)
# 出力の「audited ◯◯ packages」が実数。ls では正しく数えられない
npm ci
# 3. 依存の脆弱性を見る
npm audit
# 4. 直す
npm audit fix
# 5. 壊れていないことを確認する
npm test && npm run build
5を飛ばさないでください。
そのうえで、リポジトリの .nvmrc / .node-version / package.json の engines を確認し、バージョンを固定しているなら書き換えます。
まとめ
- Node.js に10件のCVE(2026-10-21)。修正版は v26.12.1 / v24.22.1 / v22.23.4。最重要は Brotli デコーダのRCE
- ランタイムの脆弱性と、依存ツリーの脆弱性は別物。 両方見ないと片方が残る
- 直接依存3つのこのサイトで、実際には 219パッケージ・228MB。自分で選んだのは1.4%
npm auditで 10件(critical 1・high 8)。critical は直接依存の astro にあった- 静的サイトのビルドはリクエストを処理しないので、TLSやkeep-alive系の曝露面はサーバーと違う。ただしビルド環境自体が攻撃対象なので無視はできない
.nvmrcにバージョンを固定していると、修正版が出ても古い Node でビルドされ続ける- 更新したら、テストとビルドを通してから本番へ出す
ここに書いた内容は2026年10月22日に確認したものです。判断の前に、提供元の最新の記載をご確認ください。