3
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?

【緊急】Node.jsの重大脆弱性に対応するセキュリティアップデートを安全に適用する方法

3
Last updated at Posted at 2026-10-22

はじめに

2026年10月21日、Node.jsプロジェクトが脆弱性10件を修正するセキュリティリリースを公開しました。同じ日にPHPの重大な脆弱性も話題になったため、見逃した方もいるかもしれません。

この記事では、次の内容を初心者向けに整理します。

  • 何が修正されたのか、どんな影響があるのか
  • 自分の環境が対象かどうかの確かめ方
  • 環境別の安全なアップデート手順
  • すぐ更新できないときの暫定対策

情報は2026年10月22日19時30分(JST)時点のものです。作業前にNode.js公式の発表も確認してください。

更新履歴

  • 2026年10月22日 19:30(JST):Brotliの脆弱性について公開PoC(概念実証コード)の報道を反映し、「悪用の状況は?」を書き直しました。あわせて、Brotliに公式の回避策がないこと、eMudhra対応の詳細、同梱部品のバージョン、Next.jsの対象条件を追記しました。

結論(先に読みたい人向け)

使っている系列 更新先
Node.js 26 26.12.1
Node.js 24 24.22.1
Node.js 22 22.23.4
Node.js 25 / 20以前 公式の修正版は出ません。サポート中の22・24・26へ移行してください
  • 深刻度の最高は High です。公式は「サポート終了(EOL)のバージョンは、セキュリティリリースのたびに影響を受ける」と明記しています。
  • 更新後は、動いているプロセスを再起動しないと新しいバージョンになりません。
  • 最も注意したいのは、fetch() でも踏みうる Brotliの脆弱性(CVE-2026-111497) です。10月22日には公開PoCも報じられました(詳細は後述)。
  • Next.jsを使っている場合は、Node.js本体とは別にNext.js自体の更新も必要です。

背景:Node.jsとは?

Node.jsは、JavaScriptをブラウザの外(サーバーやPC)で動かすための実行環境です。Webサイトの裏側(API)、ビルドツール、自動化スクリプトなどで使われています。

自分でNode.jsのアプリを作っていなくても、npm を使ったりフロントエンドをビルドしたりしていれば、すでに使っています。

「系列」とサポート期間

Node.jsは複数の「系列」(22、24、26など)が並行して存在し、それぞれにサポート期間があります。

用語 意味
Current 最新機能を試す系列
LTS(長期サポート) 本番運用向け。長期間セキュリティ修正が出る
EOL(サポート終了) 修正版は出ない

今回の対象は次のとおりです。

系列 状況 サポート終了(EOL)予定
26 現行版(Current)。2026年10月28日にLTS入りの予定 2029年4月30日
24 LTS。2026年10月20日から保守期間(Maintenance) 2028年4月30日
22 LTS(保守期間) 2027年4月30日
25 サポート終了済み 2026年6月1日
20以前 サポート終了済み(20系は2026年4月30日) -

LTS入りの日付などは変更されることがあります。最新の予定は公式のリリーススケジュールで確認できます。

今回修正された10件

公式の発表では、次の10件が修正されています(深刻度 High 4件 / Medium 3件 / Low 3件)。

深刻度 High(4件)

CVE 公式の見出し 影響する系列
CVE-2026-111497 Brotliデコーダーの境界外書き込みにより、リモートコード実行が可能になる 26・24・22
CVE-2026-105483 IPアドレスを全角数字で書くと、TLS証明書のホスト名検証を回避できる 26・24
CVE-2026-106069 ホスト名がゆるくIPアドレスに解決される場合に、TLS証明書のホスト名検証を回避できる 26・24・22
CVE-2026-105482 dns.resolve がNUL文字を含む名前を切り詰める 26・24・22

深刻度 Medium / Low(6件)

深刻度 CVE 公式の見出し 影響する系列
Medium CVE-2026-105481 Keep-aliveのソケットが、リクエスト送信前に書かれた応答を処理する 26・24・22
Medium CVE-2026-106072 正規でない書き方のIPv4ホスト名で、証明書のDNS名がIPエンドポイントの認証に使われてしまう 26・24・22
Medium CVE-2026-106074 crypto.randomUUID() と randomInt() の乱数キャッシュが起動スナップショットやSEAに保存され、全プロセスで同じ値を繰り返す 26・24・22
Low CVE-2026-106070 ZIPヘッダー検証に失敗した後、攻撃者が操作できる先頭バイトを返す 26のみ
Low CVE-2026-106071 Permission Modelで、ワイルドカードの検索によりファイルアクセスが広く許可される 26のみ
Low CVE-2026-106073 fs.realpathSync でPermission Modelを迂回できる 26・24・22

同梱部品の更新

Node.jsに同梱されている部品も、公開済みの脆弱性に対応するため更新されています。第三者の検証記事(lilting.ch)が各バージョンの変更履歴から整理した内容は次のとおりです。

部品 更新内容
c-ares(DNS名前解決) 26・24・22すべてで 1.34.9
undici(fetch の実装) 26:8.12.2 / 24:7.30.1 / 22:6.29.1
OpenSSL 24・22で 3.5.9
SQLite 22で 3.53.4
ca-cert(ルート証明書) 26・24・22すべてで更新(eMudhra対応を含む)

undiciの更新には、Subresource Integrityの検証と、メモリ枯渇につながる2件(WebSocketクライアントを含む)の、いずれも深刻度Moderateのアドバイザリへの対応が含まれると報じられています(The Hacker News)。

どんな影響があるのか?(初心者向け解説)

公式の発表には各脆弱性の見出しと影響する系列しか書かれていません。以下の「悪用の条件」は、公式の修正コミットと、第三者の検証記事(lilting.ch、The Hacker News)の内容をもとにしています。

① Brotliデコーダーの問題(CVE-2026-111497)

Brotliは、Web通信でよく使われるデータ圧縮の形式で、Node.jsはGoogleのBrotliライブラリを内蔵しています。展開(デコード)の処理で、本来書いてはいけないメモリ領域に書き込んでしまう欠陥です。公式はこれを「リモートコード実行が可能になる」としています。ただし、深刻度は最高の「Critical」ではなく「High」です。

修正の中身は、Brotliプロジェクト側の修正をNode.jsに取り込んだもので、不正な圧縮データを見つけた時点で早めに処理を止めるようになりました。同じ修正はBrotli本体の1.2.1、1.1.1、1.0.10でも10月21日に公開されています。

どんなときに踏むのか

  • Node.jsの fetch() は、レスポンスのヘッダーに Content-Encoding: br があると自動でBrotliを展開します。
  • つまり、自分でBrotliを扱うコードを書いていなくても、fetch() を使っていれば処理が走ります。
  • リクエストで Accept-Encoding: identity を送っても防げません。悪意あるサーバーは、それを無視して br で返せるためです。
  • 他にも、Content-Encoding: br のリクエストボディを展開するサーバー(Expressなど)や、zlib モジュールで攻撃者が用意したデータを直接展開するコードが対象になりえます。

一言でいうと
「外部のサーバーにアクセスするアプリ」も「外部からデータを受け取るアプリ」も、念のため対象と考えるのが安全です。

② TLS証明書のホスト名検証の問題(CVE-2026-105483、CVE-2026-106069、CVE-2026-106072)

HTTPS通信では、「つながった相手が本当に目的のサーバーか」を、証明書の中身(SAN)と照らし合わせて確認します。

IPv4アドレスは、実は 127.0.0.1 以外にもいろいろな書き方ができます。

  • 短縮形:127.1
  • 16進数:0x7f.0.0.1
  • 整数:2130706433
  • 先頭がゼロ:0127.0.0.1
  • 全角数字:127.0.0.1

こうした書き方をされると、Node.jsの検証が別の文字列として比較してしまい、本来通らないはずの証明書が通ることがありました。

どんなときに悪用されるのか

  • 攻撃者が、「IPアドレスの形をしたホスト名」をDNS名として入れた証明書を用意する必要があります。
  • その証明書を、クライアントが信頼している認証局(CA)から発行してもらう必要もあります。
  • 全角数字の件(CVE-2026-105483)の修正コミットでは、悪用は容易ではないとされています。公式の深刻度は High ですが、修正した開発者側は「低い深刻度で、悪用は難しい」と評価している点は知っておくとよいでしょう。

一言でいうと
「条件は厳しいが、暗号化通信の『相手確認』という土台に関わる問題」です。

③ dns.resolve とNUL文字の問題(CVE-2026-105482)

内部で使われているC言語のライブラリは、NUL文字(\0)を「文字列の終わり」とみなします。そのため、JavaScriptの文字列の途中にNULが入っていると、手前までしか名前解決に渡されません。

// 修正前は、example.com が引かれてしまう
dns.resolve4('example.com\0.trusted.corp');

「.trusted.corp で終わる名前だけ許可する」というチェックをしていても、チェックを通った名前と実際に引かれる名前が食い違うことになります。修正版では、NULを含む引数は ERR_INVALID_ARG_VALUE で拒否されます。

④ 乱数の問題(CVE-2026-106074)

起動スナップショットや単一実行ファイル(SEA)に乱数のキャッシュが保存されてしまい、そこから起動したプロセスが同じ値を繰り返す問題です。スナップショットやSEAを使っていない通常の起動では、影響の対象外と考えられます。

⑤ Permission Modelの問題(CVE-2026-106071、CVE-2026-106073)

Permission Modelは、--permission オプションで起動したときにファイルアクセスなどを制限する仕組みです。このオプションを使っていなければ、この2件は関係ありません。

⑥ その他

  • CVE-2026-105481(Keep-alive) と CVE-2026-106070(ZIP) は、公式の見出し以上の詳細は公開されていません。

eMudhraの認証局への対応

今回の更新では、インドの認証局 eMudhra の中間CAの秘密鍵が侵害された件への対応も入っています。

  • Node.jsはMozillaのルート証明書一覧を使っていますが、標準では失効確認(オンラインでの確認)を行いません。そのため、これまでは侵害された鍵を通る証明書チェーンも通ってしまいました。
  • 修正版では、問題のある中間CAの公開鍵8つを内蔵のブロックリストに入れ、該当するチェーンを CERT_REVOKED として拒否します。あわせて、同梱のルート証明書一覧からeMudhra(emSign)のルート3つが外されました。
  • 更新前に確立したTLSセッションを再開する接続は、セッションの有効期限が切れるまで再チェックされないと報じられています。更新後の再起動が大切な理由のひとつです。
  • サポート終了の系列には、このブロックは入りません。
  • Go言語も、10月20日の更新で同じブロックを入れています。

悪用の状況は?

2026年10月22日(JST)時点で、実際の攻撃(in the wild)の報告は見つかっていません。ただし、公開PoCが出ています。

  • 公式の発表には、実際に悪用されたかどうかは書かれていません。
  • 米国東部時間10月21日14時の時点では、攻撃も公開エクスプロイトも報じられていないとするブログがありました(LFW)。ただし、これはその時点だけの情報です。
  • その後、10月22日に公開されたPoCがあると報じられています(The Hacker News)。同記事によると、そのPoCでコード実行に至ったのは意図的に弱めたテスト用ビルドだけです。標準のNode.jsビルドでは、作者自身がクラッシュと、プロセスメモリの一部の読み取りにとどまり、コード実行までは達成できていないと報告しているとのことです。
  • 修正版のNode.jsは、このPoCが使う不正な入力を拒否します。

「標準ビルドでコード実行に成功していない」=「安全」ではありません。 PoCが公開されたことで、手法の研究が進んで攻撃が現実的になる可能性があります。「公開PoCがある」「実攻撃の報告はまだない」の両方を踏まえ、早めに更新するのが安全です。

最新状況は、公式やJPCERT/CCで確認してください。

手順1:自分の環境を確認する

node -v
# 例: v24.22.0

そして、どこで動いているかを書き出します。

  • 自分のPC(開発環境)
  • サーバー(VPS、クラウド)
  • Dockerコンテナ
  • Vercel / Netlify などのホスティング
  • CI/CD(GitHub Actionsなど)のビルド環境

公開サイトが「ビルド済みの静的ファイルを配るだけ」の場合、公開中のサイトが直接攻撃されることはありません。ただし、ビルドに使うNode.jsは更新対象です。ビルド中に外部へ fetch() するスクリプトがある場合は、特に早めに更新してください。

手順2:更新前の準備

  1. いまのバージョンをメモする(戻せるように)
  2. package-lock.json があるか確認する
  3. テストを実行して、更新前の状態が正常か確認する
  4. 可能なら、検証環境で先に試す
node -v
npm -v
npm test   # テストがあれば

手順3:環境別アップデート方法

パターンA:nvm

# 24系の場合
nvm install 24.22.1
nvm use 24.22.1
nvm alias default 24.22.1
node -v   # v24.22.1 ならOK

22系なら 22.23.4、26系なら 26.12.1 を指定します。

パターンB:fnm / Volta

# fnm
fnm install 24.22.1
fnm use 24.22.1
fnm default 24.22.1

# Volta
volta install node@24.22.1

パターンC:公式インストーラー(Windows / macOS)

  1. Node.js公式のダウンロードページを開く
  2. 自分の系列の修正版を選んでインストール(上書きでOK)
  3. ターミナルを開き直して node -v で確認

パターンD:Docker

イメージを作り直さないと更新されません。

# 変更前
FROM node:24.22.0-slim

# 変更後
FROM node:24.22.1-slim
docker pull node:24.22.1-slim   # 先に最新を取得
docker build --no-cache -t my-app:latest .
docker compose up -d

FROM node:24 のようにバージョンを固定していなくても、キャッシュが残っていると古いままのことがあるので、先に docker pull します。公式イメージのタグ(node:24.22.1、node:22.23.4、node:26.12.1)は、10月21日の夜(JST)にDocker Hubへ公開されたと報告されています。

パターンE:Homebrew / OSのパッケージ管理

brew upgrade node   # node@24 / node@22 の場合は名前を合わせる

Homebrewなどは、公式リリースから反映まで時間がかかることがあります。実際に、10月21日の21時20分(JST)ごろの時点では、node が26.12.0、node@24 が24.22.0、node@22 が22.23.3のままだったと報告されています。更新後に必ず node -v で確認し、古いままなら nvm や公式インストーラーを使いましょう。

パターンF:Vercel / Netlify などのホスティング

実行環境の修正はサービス側が行うことが多いですが、使うNode.jsの系列は自分で設定している場合があります。

  • プロジェクト設定の「Node.js Version」を確認する
  • サポート終了の系列(20以下・25)なら、22・24・26に変更して再デプロイ

手順4:アプリを再起動する(忘れがち)

Node.jsを更新しても、動いているプロセスは古いバージョンのままです。

# pm2
pm2 restart all

# systemd
sudo systemctl restart your-app

# Docker
docker compose up -d --force-recreate

手順5:依存パッケージを入れ直す

Node.jsのバージョンが変わると、ネイティブモジュールが動かなくなることがあります。

rm -rf node_modules
npm ci
npm test
npm run build

npm ci は、package-lock.json どおりに再現性のある環境を作ります。

手順6:Next.jsを使っている場合

Next.jsは2026年10月14日に、定例外のセキュリティ更新を公開しています。9月のセキュリティリリースで、上流の依存ライブラリの都合により先送りされていた2件の修正を含みます。

  • 修正版:16.4.1(Active LTS)、15.5.28(Maintenance LTS)
  • 内容:重大(Critical)2件、高(High)1件
深刻度 内容 条件・回避策
Critical use cache 関数が複数の型付き配列を返すと、認証なしでリモートコード実行が可能になる App RouterでCache Componentsを使っている場合。既知の回避策なし
Critical(CVE-2026-96889) 画像最適化API(SVG)で、上流ライブラリのメモリ問題からリモートコード実行が可能になる glibcベースのLinuxで動かす場合。回避策は、Next.jsが使う sharp を 0.35.5以降にすること
High Server Actionsを使うApp Routerで、細工したリクエストによりCPUを使い切り、DoSになる App Routerで、Server Actionが1つ以上ある場合。Pages Routerや、Server Actionを使っていない場合は対象外
# 16系
npm install next@16.4.1

# 15系
npm install next@15.5.28

Node.jsだけ、Next.jsだけの更新では足りません。両方を更新してください。 use cache の件には回避策がないため、該当しない構成でも更新が推奨されています。

詳しい対象条件はNext.js公式ブログを確認してください。

手順7:更新後のチェックリスト

  • node -v が修正版になっている
  • アプリを再起動した
  • 主要な画面・機能が動く
  • 外部APIとのHTTPS通信が成功する
  • エラーログに見慣れないエラーが出ていない
  • CI/CD(ビルド・デプロイ)が成功する

戻し方

# nvm の場合
nvm use 24.22.0

Dockerの場合は、Dockerfileを前のバージョンに戻して再ビルドします。ただし、戻すと脆弱性が残るので、あくまで一時的な措置にしてください。

すぐ更新できない場合の暫定対策

以下は更新までのつなぎです。根本対策はアップデートです。

NUL文字(CVE-2026-105482)
外部から受け取った文字列を dns.resolve* に渡す前に、NULを含まないか確認します。

if (name.includes('\0')) throw new Error('invalid name');

IPアドレスの別表記(TLSの問題)
外部入力のホスト名に接続する前に、「IPに見えないが正規化するとIPになる」ホストを拒否します。

const net = require('node:net');
const url = require('node:url');

function isNonCanonicalIP(host) {
  return !net.isIP(host) && net.isIP(url.domainToASCII(host)) !== 0;
}

Brotli(CVE-2026-111497)
公式の発表に、一時的な回避策の記載はありません。 Node.js自身の設定では防げないと報じられています。

  • OSのパッケージとして入っているbrotliを更新しても、Node.jsに同梱されているBrotliは更新されません。 Node.js本体の更新が必要です。
  • Vercelは、10月21日に受信リクエストを対象にしたファイアウォールルールを追加したと報じられています。ただし、アプリが外部から取得したBrotli応答は対象外で、更新の代わりにはなりません。
  • 補助的な方法として、リクエストボディについてはリバースプロキシで Content-Encoding: br を拒否することも考えられます。ただしこれは公式の回避策ではなく、fetch() で受け取る応答も防げません。根本対策は更新です。

サポート終了の系列を使っている場合
修正版は出ません。22・24・26への移行計画を立ててください。

まとめ

  • 2026年10月21日、Node.jsが脆弱性10件(High 4件)を修正した。
  • 更新先は 26.12.1 / 24.22.1 / 22.23.4。
  • 25と20以下は修正版が出ないため、サポート中の系列への移行が必要。
  • 最も注意したいのは、fetch() でも踏みうる Brotliの問題(CVE-2026-111497)。10月22日に公開PoCが報じられたが、標準ビルドでのコード実行は確認されておらず、実攻撃の報告もない(10月22日時点)。公式の回避策はないので、更新が唯一の対策。
  • 更新後は再起動と動作確認を忘れずに。Next.jsを使っているならNext.jsも更新する。

参考リンク

3
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
3
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?