
Node.jsにも、脆弱性は見つかっています。2026年10月21日、Node.jsプロジェクトは、10件の脆弱性(深刻度Highが4件、Mediumが3件、Lowが3件)を修正するセキュリティリリースを公開しました(Node.js公式ブログ)。修正版は、22.23.4、24.22.1、26.12.1です。PHPの「php2shell」とは、別の問題です。
この記事は、Node.jsを運用するエンジニア向けに、Node.js公式ブログ、リリースノート(24.22.1、22.23.4)、CVEレコードなどの一次情報を軸にして、確認できた事実と、確認できていない点を分けて整理したものです。出典は、各記述のそばに示しています。情報は、2026年10月22日の時点のものです。
Node.jsの公式のリリーススケジュール(nodejs/Releaseのschedule.json)にもとづく、各系列の状況です。
| 系列 | 状態(2026年10月22日時点) | 今回の修正版 | EOL(サポート終了)の予定 |
|---|---|---|---|
| 18.x | EOL | なし | 2025年4月30日 |
| 20.x | EOL | なし | 2026年4月30日 |
| 22.x | Maintenance LTS(2025年10月21日から) | 22.23.4 | 2027年4月30日 |
| 24.x | Maintenance LTS(2026年10月20日から) | 24.22.1 | 2028年4月30日 |
| 25.x | EOL | なし | 2026年6月1日 |
| 26.x | Current(10月28日にLTSへ) | 26.12.1 | 2029年4月30日 |
24.xは、10月20日に、Active LTSからMaintenance LTSに移りました。Maintenanceは、重大なバグとセキュリティの修正だけが入る段階です。26.xは、10月28日にLTSになる予定です。
Node.js公式ブログには、各脆弱性の原因や攻撃条件の詳しい説明はなく、題名と、影響する系列、報告者、修正者が書かれています。下の表の「修正の内容」は、24.22.1と22.23.4のリリースノートに書かれた、修正のコミットの題名です。
| CVE | 深刻度 | 題名(原文の意味) | 影響する系列 | 修正の内容 |
|---|---|---|---|---|
| CVE-2026-111497 | High | Brotliのデコーダの範囲外書き込みで、リモートコード実行が可能になる | 26.x、24.x、22.x | Brotliの修正を取り込み(cherry-pick) |
| CVE-2026-105482 | High | dns.resolveが、NUL文字を含む名前を切り詰める |
26.x、24.x、22.x | dns.resolveの入力に、NULバイトがないかを検証 |
| CVE-2026-105483 | High | IPアドレスが全角数字で書かれていると、TLSの証明書のホスト名検証を回避できる | 26.x、24.x | IPの正規化のリグレッションを修正 |
| CVE-2026-106069 | High | ホスト名が、緩くIPアドレスとして解釈される場合に、TLSのホスト名検証を回避できる | 26.x、24.x、22.x | 非正規のIPアドレスを、TLSで拒否 |
| CVE-2026-105481 | Medium | keep-aliveのソケットが、リクエストの送信前に書き込まれたレスポンスを処理する | 26.x、24.x、22.x | HTTPエージェントの、データの保護が、I/Oなしでも働くように修正 |
| CVE-2026-106072 | Medium | 非正規のIPv4のホスト名で、証明書のDNS SANが、IPのエンドポイントの認証に使えてしまう | 26.x、24.x、22.x | 非正規のIPアドレスを、TLSで拒否(106069と同じ修正) |
| CVE-2026-106074 | Medium | crypto.randomUUID()とrandomInt()の乱数キャッシュが、スナップショットやSEAに保存され、全プロセスで同じ値が繰り返される |
26.x、24.x、22.x | スナップショットをまたいで、乱数キャッシュをリセット |
| CVE-2026-106070 | Low | ZIPのヘッダー検証に失敗したあと、ZipFileが攻撃者の制御するバイト列を返す |
26.xのみ | 未確認(26.xのリリースノートは未取得) |
| CVE-2026-106071 | Low | Permission Modelで、ワイルドカードの検索により、ファイルシステムの権限が過剰に付与される | 26.xのみ | 未確認(26.xのリリースノートは未取得) |
| CVE-2026-106073 | Low | fs.realpathSyncで、Permission Modelを回避できる |
26.x、24.x、22.x | realpathSyncでPermission Modelを確認 |
Node.jsは、各CVEのCVSSスコアを公表していません(公式ブログ)。なお、各CVEのレコード(cve.org)は、10月22日の時点で、私が確認した4件(CVE-2026-111497、105482、105483、106069)のうち、取得できたのは、CVE-2026-111497だけでした。
Node.js公式ブログの題名は、「Brotliのデコーダの範囲外書き込みで、リモートコード実行が可能になる」です。CVEレコードによると、原因は、Node.jsではなく、Googleのgoogle/brotliライブラリです。
Node.jsの修正は、このBrotliの修正を取り込んだものです(24.22.1のリリースノート)。報告者として、OpenAI Codex Securityが挙がっています(公式ブログ)。
どこが影響を受けるかについて、Vercelの告知が、次のように説明しています。Node.jsのプロセスが、攻撃者の制御するBrotliのデータを、リクエストのボディや、取得したレスポンスとして展開する場合に、影響を受けます。Node.jsが、勝手にBrotliのデータを展開するわけではありません。公式ブログは、具体的にどのAPIが該当するかを、示していません。
私見ですが、zlibのBrotli展開(zlib.brotliDecompressなど)や、Content-Encoding: brのリクエストを展開するミドルウェア、外部のAPIから取得したBrotli圧縮のレスポンスを展開する処理は、確認の対象になると思います。
Vercelは、未修正のバージョンで、研究者がプロセスのメモリの漏えいと、コマンドの実行を実証したと述べています(Vercelの告知)。実際の攻撃(in the wild)については、記載がありません。
Brotliは、Node.js以外にも、多くのソフトウェアに組み込まれています。ライブラリそのものの脆弱性なので、ブラウザ、HTTPクライアント、Webサーバーのモジュール、各言語のバインディングなど、Brotliを使う他の製品も、それぞれの更新の確認が必要です。なお、google/brotliのGitHubのセキュリティアドバイザリには、10月22日の時点で、公開されたものはありませんでした。
CVE-2026-105483、CVE-2026-106069、CVE-2026-106072は、いずれも、IPアドレスの「正規でない表記」(全角数字、緩くIPアドレスと解釈される表記など)をめぐって、TLSの証明書のホスト名検証が、期待どおりに働かない問題です。修正版では、非正規のIPアドレスを、TLSで拒否するようになりました(リリースノート)。
私見ですが、設定や環境変数で、接続先のIPアドレスを、通常と違う表記で書いている場合、更新後に、接続が拒否されるおそれがあります。更新後は、外部への接続のテストを、必ず行ってください。
dns.resolveが、NUL文字を含む名前を、途中で切り詰めて解決します。修正で、入力のNULバイトの検証が入りました(リリースノート)randomUUID()とrandomInt()の乱数キャッシュが、ユーザーのスナップショットやSEA(単一の実行ファイル)に保存されます。その結果、同じスナップショットから起動した全プロセスで、同じ値が繰り返されます--permission)に関するものです。Permission Modelを使っている場合は、確認してください今回のリリースでは、依存関係も更新されています。24.22.1のリリースノートでは、次のとおりです。
| 依存関係 | 24.22.1 |
|---|---|
| OpenSSL | 3.5.9 |
| undici | 7.30.1 |
| c-ares | 1.34.9 |
| ルート証明書(NSS) | 3.131.1 |
| tzdata(タイムゾーン) | 2026e |
22.23.4では、undiciが6.29.1、SQLiteが3.53.4で、そのほかは同じです。公式ブログは、依存関係の更新の項目に、「ca-cert(eMudhra Intermediate CA Compromise)」を挙げています。eMudhraの中間認証局に関する問題への対応として、ルート証明書が更新されました。ただし、この件の詳細は、Node.jsの公式ブログには書かれていません。詳細は、認証局やブラウザの発表で確認してください。
まず、本番、CI、コンテナで、実際に使っているバージョンを確認します。
node -v
nvmを使う例です。
nvm install 24.22.1 # 22系なら 22.23.4、26系なら 26.12.1
nvm use 24.22.1
Dockerは、ベースイメージを取り込み直して、キャッシュを使わずに再ビルドし、コンテナ内のバージョンを確認します。
docker build --pull --no-cache -t myapp .
docker run --rm myapp node -v
コンテナの再ビルドの例は、ToolScopeの解説記事(二次情報)でも紹介されています。公式のDockerイメージ(nodejs/docker-node)の配信状況は、ここでは確認できていません。取り込み直して、node -vで確認してください。.nvmrc、package.jsonのengines、CIのsetup-nodeなどで、バージョンを固定している場合は、そこも更新が必要です。
スナップショットやSEAを使っている場合は、修正版のランタイムで、作り直してください。公式ブログに、再ビルドの記載はありません。ただ、すでに保存された乱数キャッシュは、作り直さない限り、残ると考えられます(私見)。
Vercelの告知によると、Vercelは、10月21日に、この脆弱性に対するWAFのルールを、全プロジェクトに展開し、自動で適用しています。ただし、Vercelのネットワークを通らないトラフィックや、関数が外部のサーバーから取得したレスポンスは、対象外です。管理対象のランタイムは、修正版に更新を進めています。利用者の側で必要な対応は、次のとおりです。
Node.jsの更新とは別に、Next.jsが、10月14日に、臨時のセキュリティ更新を公開しています。修正版は、16.4.1(Active LTS)と15.5.28(Maintenance LTS)です。Critical 2件とHigh 1件が修正されています。
use cacheで型付き配列を返す場合の、認証不要のRCE(Critical。GHSA-673q-mjm6-r5xr)。回避策はなく、更新が必要ですsharpを0.35.5以降にできますNext.jsを使っている場合は、Node.jsの更新と、Next.jsの更新の、両方を確認してください。
| 項目 | 内容 | 確度 |
|---|---|---|
| 公式ブログ | 悪用の有無について、記載なし。回避策も、記載なし | 一次情報 |
| 実証 | Vercelは、未修正のバージョンで、研究者がメモリの漏えいとコマンドの実行を実証したと述べている | ベンダーの説明 |
| 実際の攻撃 | 10月22日の時点で、実際の攻撃の報告は、私が確認した範囲では見つからなかった | 確認されていない |
| 深刻度 | Node.jsはHigh(公式ブログ)。BrotliのCVEレコードは、CVSS v4.0で9.2(CRITICAL) | 評価が異なる |
| 各CVEの詳細 | 公式ブログは、題名中心。確認した4件のうち3件のCVEレコードは、取得時点で未公開 | 詳細は限定的 |
実際の攻撃の報告がないことは、安全の証明ではありません。Brotliは、Node.js以外でも使われているため、広く確認が必要です。
Node.jsのリリース計画も、変わります。公式の告知(「Evolving the Node.js Release Schedule」)によると、Node.js 27から、メジャーリリースは年1回(4月)になり、10月にLTSに昇格します。奇数・偶数の区別はなくなり、すべてのリリースがLTSになります。LTSの期間は30か月です。公式は、保守の負担が理由の1つだと説明しています。4〜5本の系列で、セキュリティリリースを維持するのは困難になっていた、と述べています。
schedule.jsonでは、27.xのAlphaが10月28日から、27.0.0が2027年4月22日の予定です。26.xは、旧方式の最後のリリースです。
今回の件に関わる、現実的な判断は、次のとおりです。
今日のうちに
今週のうちに
今期のうちに
