Node.jsプロジェクトは2026年10月21日、10件の脆弱性を修正したセキュリティアップデート「Node.js 26.12.1」「24.22.1」「22.23.4」を公開した。修正された脆弱性のうち4件は深刻度が「High(高)」と評価されており、Brotliのデコード処理においてリモートコード実行につながる可能性がある問題も含まれている。さらに、TLS証明書の検証を回避できる問題や、DNSの名前解決に関する不具合など、外部との通信の安全性に関わる脆弱性も修正された。
今回の更新では、アプリケーションの起動状態を保存する「スナップショット」から復元した際に、同じ乱数が繰り返し生成される問題にも対処している。このため、通常のNode.js実行環境だけでなく、単一実行ファイル(SEA)として配布しているアプリケーションについても確認が必要だ。修正版への更新に加え、外部サービスとのTLS接続や、修正版のNode.jsで作り直した配布物に修正が反映されているかが重要な確認事項となる。
3系列のセキュリティ更新を公開、脆弱性10件の影響範囲は異なる
Node.jsプロジェクトは10月21日の公式セキュリティ告知で、26系、24系、22系の3系列に対する修正版を公開した。26系はCurrent、24系と22系は長期サポート版(LTS)として提供されており、いずれも今回の更新で深刻度Highの脆弱性が修正されている。ただし、影響を受ける脆弱性は系列によって異なり、すべての修正が3系列に共通しているわけではない。
| 系列 | 修正版 | リリース区分 | 全角数字によるTLS検証回避(CVE-2026-105483) |
|---|---|---|---|
| 26系 | 26.12.1 | Current | 影響あり |
| 24系 | 24.22.1 | LTS | 影響あり |
| 22系 | 22.23.4 | LTS | 対象外 |
今回公表された10件のCVEは、深刻度別にHighが4件、Medium(中)が3件、Low(低)が3件となっている。特に深刻度が高いのは、Brotliデコーダーにおける境界外書き込みの脆弱性「CVE-2026-111497」だ。Brotliはデータの圧縮・展開に使用される技術で、今回の問題では、デコード処理が確保されたメモリ領域の範囲を超えてデータを書き込む可能性がある。Node.jsプロジェクトは、この不具合がリモートコード実行につながり得ると説明しており、26系、24系、22系のすべてが影響を受ける。ただし、攻撃が成立する具体的な通信経路や、実際の悪用が確認されているかどうかについては、公式告知で明らかにされていない。
深刻度Lowの3件についても、影響範囲は異なる。「CVE-2026-106070」は、ZIPヘッダーの検証に失敗した後も、攻撃者が操作できるデータの一部を返してしまう問題だ。また、「CVE-2026-106071」は、Node.jsの権限モデルでワイルドカードを使ったファイルパスの検索に問題があり、本来より広い範囲のファイルアクセスが許可される可能性がある。これら2件は26系のみが対象となる。一方、fs.realpathSync()を通じて権限モデルの制限を回避できる「CVE-2026-106073」は、3系列すべてに影響する。
したがって、22系で全角数字によるTLS検証回避の問題が発生しないからといって、今回の更新を見送ってよいわけではない。Brotliの脆弱性をはじめ、別のTLS検証回避やDNSの問題などは22系にも存在する。利用している系列ごとの修正内容を確認し、対応するセキュリティアップデートを適用する必要がある。
TLS証明書の検証回避に関する複数の脆弱性を修正
深刻度Highの残る3件は、DNSの名前解決やTLS証明書の検証に関わる問題だ。その一つである「CVE-2026-105482」は、dns.resolve()にNUL文字を含む名前を渡すと、文字列が途中で切り詰められる脆弱性で、26系、24系、22系のすべてが影響を受ける。NUL文字は文字列の終端を表すために使われる特殊な文字で、入力された名前と実際に名前解決される名前が食い違う可能性がある。アプリケーションが入力された名前を基にアクセス制御などを行っている場合、この不一致がセキュリティ上の問題につながり得る。
TLS証明書の検証では、IPアドレスの表記や解釈に関する2件の脆弱性が修正された。「CVE-2026-105483」は、IPアドレスを全角数字で表記した場合にホスト名の検証を回避できる問題で、26系と24系が対象となる。一方、「CVE-2026-106069」は、ホスト名の緩い解釈によって入力がIPアドレスとして扱われ、証明書の検証を回避できる問題だ。こちらは26系、24系、22系のすべてに影響する。いずれも、通信先を表す文字列がどのように解釈されるかによって、証明書の検証結果に不整合が生じる点が問題となっている。
TLS接続では、証明書が信頼できる認証局によって発行されていることに加え、その証明書が実際の接続先に対応していることを確かめる必要がある。Node.jsのTLS API仕様によると、tls.checkServerIdentity()は、証明書が信頼された認証局から発行されたかなどの検証を通過した後に呼び出され、指定されたホスト名またはIPアドレスが証明書と一致するかを確認する。今回の脆弱性は、この照合処理に問題があると、通信が暗号化されていても接続相手の正当性を適切に確認できない可能性があることを示している。
深刻度Mediumの「CVE-2026-106072」も、IPアドレスの解釈と証明書の検証に関わる問題だ。標準的ではないIPv4アドレス表記に対して証明書の検証を誤り、本来はDNS名の認証に使う証明書のSubject Alternative Name(DNS SAN)が、IPアドレスで指定された接続先の認証に使用されてしまう可能性がある。この問題も3系列すべてに影響する。Node.jsから外部APIや他のサービスへ接続するアプリケーションでは、接続先の名前やIPアドレスの指定方法に加え、独自の証明書検証処理を使用していないかも確認する必要がある。
このほか、深刻度Mediumの「CVE-2026-105481」は、HTTPのkeep-alive接続で再利用されるソケットが、リクエストを送信する前に書き込まれた応答を処理してしまう問題だ。keep-aliveは、HTTP通信のたびに新しい接続を確立するのではなく、既存の接続を再利用する仕組みで、こちらも3系列すべてが影響を受ける。今回のセキュリティ更新は、外部から受け取るリクエストの処理だけでなく、Node.jsが外部サービスと通信する際の安全性にも関わっている。
eMudhraの中間認証局の秘密鍵侵害に対応、公開鍵の遮断リストを導入
今回の更新には、eMudhraの中間認証局の秘密鍵侵害に対応する証明書検証機能の強化も含まれている。これは、証明書に記載されたホスト名が接続先と一致するかという前述の問題とは異なり、証明書の信頼性をどのように判断するかに関わる変更だ。通常、TLS証明書の検証では、接続先の証明書から中間認証局を経由し、信頼されたルート認証局へとつながる「証明書チェーン」を確認する。しかし、中間認証局の秘密鍵が侵害されると、信頼されたルート認証局につながる証明書チェーンであっても、安全性を保証できなくなる可能性がある。
Node.jsのGitHubでマージされた修正PRによると、Node.jsはMozillaのルート証明書ストアを組み込んでいるものの、ブラウザーで使われるCRLSetやOneCRLに相当する失効情報の仕組みや、標準でのオンライン失効確認機能を備えていない。そのため、秘密鍵が侵害された中間認証局であっても、証明書チェーンが信頼済みのルート認証局につながっていれば、検証を通過する可能性があった。一方、問題のある中間認証局につながるルート認証局を信頼対象から外してしまうと、同じルート認証局を利用する別の正当な中間認証局まで影響を受ける。
そこでNode.jsは、問題のある公開鍵を個別に識別して拒否する仕組みを追加した。具体的には、証明書の公開鍵情報であるSubjectPublicKeyInfo(SPKI)をSHA-256でハッシュ化し、その値を組み込みの遮断リストと照合する。初期状態では、2026年10月に秘密鍵の侵害が報告されたeMudhraおよびemSignの中間認証局8件が登録されている。証明書チェーンにリストと一致する公開鍵が含まれていた場合、通常の証明書検証処理を通じて拒否し、失効を表すCERT_REVOKEDとして扱う仕組みだ。
ただし、この変更によってすべてのTLS接続が自動的に安全になるわけではない。証明書の検証に失敗した場合に接続を拒否するかどうかは、rejectUnauthorizedの設定にも左右される。アプリケーション側で証明書検証を無効化していたり、独自の検証処理を実装していたりする場合には、Node.js本体を更新するだけで十分とは限らない。
また、修正PRには、更新前に確立されたTLSセッションを再開する際の制約も記されている。更新前のセッションを再利用する場合、証明書チェーンの検証は改めて実行されず、その状態はセッションの有効期限が切れるまで続く可能性がある。このため、更新後の確認では既存の接続を再利用するだけでなく、新しいTLS接続を確立し、証明書の検証が適切に機能するかを確かめることが重要だ。ルート証明書ストアのバージョンを確認するだけでは、今回追加された公開鍵の遮断処理が正しく動作していることまでは判断できない。
起動時スナップショットの復元で同じ乱数が繰り返される問題
深刻度Mediumの「CVE-2026-106074」は、Node.jsの乱数生成機能と起動時スナップショットの組み合わせによって発生する脆弱性だ。対象となるのはcrypto.randomUUID()やcrypto.randomInt()が使用する乱数キャッシュで、起動時スナップショットや単一実行ファイル(SEA)にこのキャッシュが保存されると、復元した複数のプロセスで同じ乱数が繰り返し使われる可能性がある。この問題は26系、24系、22系のすべてに影響する。
起動時スナップショットとは、アプリケーションの初期化が完了した状態を保存し、次回以降の起動時に復元することで、起動時間を短縮する仕組みだ。Node.jsのSEA仕様によると、useSnapshotを有効にすると、ビルド時にメインスクリプトを実行し、その時点で初期化された状態を実行ファイルへ組み込める。利用者の環境では、保存された状態から処理を再開するため、初期化の一部を繰り返す必要がなくなる。
ところが、スナップショットの作成時に生成された未使用の乱数まで保存されると、同じスナップショットから起動したプロセスが同じ値を再利用してしまう。乱数は識別子の生成などに利用されるため、本来は異なるプロセスで独立して生成されるべき値が重複することは問題となる。公開された修正コミットでは、スナップショットの保存と復元に伴って乱数キャッシュを初期化し直す変更が加えられた。
修正では、利用者が登録したシリアライズ処理のコールバックが終了した後と、デシリアライズ処理のコールバックが始まる前の2段階でキャッシュを消去する。これは、保存時のコールバックが終了した後も、マイクロタスクや終了処理などによって乱数キャッシュが再び満たされる可能性があるためだ。復元時にもキャッシュを消去することで、保存された乱数が別のプロセスで再利用されるのを防ぐ。なお、この脆弱性は起動時スナップショットに保存された乱数キャッシュに関する問題であり、通常の方法で起動したすべてのNode.jsプロセスが同じ乱数を生成するという意味ではない。
特に注意が必要なのは、Node.jsを組み込んだ単一実行ファイルとしてアプリケーションを配布している場合だ。SEAは、Node.jsがインストールされていない環境でもアプリケーションを実行できる配布形式であり、生成時に使用したNode.jsの実行環境を含んでいる。そのため、開発用コンピューターにインストールされたNode.jsを更新しても、すでに配布した実行ファイルが自動的に修正版へ置き換わるわけではない。
起動時スナップショットを使用するSEAでは、修正版のNode.jsを使って実行ファイルを再生成し、配布先のアプリケーションも更新する必要がある。また、SEAの準備データを生成するNode.jsと、それを組み込む実行ファイルのNode.jsはバージョンを一致させる必要がある。更新時には開発環境だけでなく、ビルドに使用するNode.jsと、最終的に配布される実行ファイルの両方を確認することが重要となる。
更新後はTLS接続と配布物への修正反映を確認
今回のセキュリティ更新では、TLS証明書による接続先の確認、侵害された中間認証局の遮断、起動時スナップショットに保存される乱数キャッシュという、異なる仕組みに対する修正が行われた。それぞれ修正の対象や確認方法が異なるため、Node.jsのバージョン番号を確認するだけでなく、実際にアプリケーションが使用する機能や配布形態に応じた検証が必要になる。
公式のセキュリティ告知とAPI仕様、公開された修正内容を踏まえると、更新後に確認すべき主な事項は次のように整理できる。
| 修正対象 | 更新後に確認すること | 注意点 |
|---|---|---|
| TLSのホスト名検証 | 外部APIなどへのTLS接続と、証明書の照合が正常に機能するか | 独自の証明書検証関数や設定も確認する |
| 侵害された中間認証局の遮断 | 新しいTLS接続で証明書チェーンが適切に検証されるか | 更新前に確立されたセッションの再開時には再検証されない |
| 起動時の乱数キャッシュ | 修正版でスナップショットやSEAを再生成し、配布物にも修正が反映されているか | ホスト側のNode.jsと、配布された実行ファイルのバージョンを区別する |
この表は、今回の修正内容に基づいて運用上の確認事項を整理したものであり、すべてのアプリケーションに適用できる公式の検証手順ではない。実際の安全性は、アプリケーションの構成や独自の設定、使用する機能によって異なる。特にTLS接続では、標準の証明書検証を無効化していないか、修正後も外部サービスとの通信が正常に行えるかを確認する必要がある。
また、今回の更新ではNode.js本体の脆弱性に加え、組み込まれている依存ライブラリの更新も行われた。公式告知によると、c-aresとUndiciは3系列すべてで更新され、OpenSSLは24系と22系、SQLiteは22系が更新対象となっている。Node.js 24.22.1と22.23.4のリリースノートにも、それぞれのライブラリ更新が記載されている。アプリケーションで使用するnpmパッケージを更新するだけでなく、実行基盤となるNode.js本体に必要な修正が反映されているかを確認しなければならない。
権限モデルに関する脆弱性についても、修正によって保証される範囲を正しく理解する必要がある。Node.jsの権限モデルに関する公式仕様では、この機能は信頼できるコードが意図せずファイルなどのリソースにアクセスするのを制限するためのものであり、悪意あるコードに対する安全性を保証する仕組みではないと明記されている。今回の修正によって特定の権限チェックの不具合は解消されるものの、権限モデルが未信頼コードを安全に実行するためのサンドボックスになるわけではない。
Node.jsプロジェクトは、サポートが終了したバージョンもセキュリティ上の問題の影響を受けるとして、サポート対象の最新バージョンへ更新するよう呼びかけている。今回の更新では、Brotliのリモートコード実行につながる脆弱性に加え、外向きのTLS接続やスナップショットの復元など、アプリケーションの内部処理にも修正が及んでいる。更新を完了したと判断するには、管理端末にインストールされたNode.jsだけでなく、稼働中のサービスや配布先の実行ファイルにも修正が反映されていることを確認する必要がある。



