Node.js、サーバーのクラッシュや機密データ漏えいを招く16件のセキュリティ脆弱性を修正

Node.jsプロジェクトは2026年11月11日、複数のラインを対象とした連携セキュリティリリースを公開しました。対象は22.x、24.x、26.xの各ラインで、v22.23.5、v24.22.3、v26.13.1が提供されています。

今回のリリースでは16件の脆弱性を修正しました。深刻度の内訳は、High(高)が7件、Medium(中)が6件、Low(低)が3件です。あわせて、llhttp、undici、sqliteのアップデートも含まれています。特に深刻な欠陥では、認証を受けていないリモートの攻撃者がプロセスを異常終了させたり、ヒープメモリを破壊したり、他の接続に属するデータを読み取ったりすることが可能です。

被害が最も大きいのはHTTP/2スタックです。CVE-2026-123863は、~Http2Session()に存在する到達可能なアサーションの欠陥です。nghttp2が割り当てたヘッダーバッファを保持するストリームがセッションより長く存続すると、CHECK_EQ(current_nghttp2_memory_, 0)が失敗し、プロセスが終了します。

これは、以前のパッチでは修正されなかったCVE-2024-27983の亜種です。CVE-2026-123865は、CVE-2026-48937の不完全な修正に起因します。ピアがGOAWAY(NO_ERROR)を送信した後、過大なフレームヘッダーなどによるプロトコルエラーを引き起こすと、ソケットがCLOSE_WAIT状態のまま残り、セッション状態がメモリ上に無期限に保持されます。

メモリ破壊の欠陥も相次いでいます。HTTP/2実装におけるメモリ安全性のバグは、これまでも繰り返しサービス拒否(DoS)攻撃に悪用されてきました。今回のNode.jsの脆弱性では、ヒープレベルの攻撃手段がさらに加わります。

複数の欠陥は、ヒープの内容を直接露出させます。CVE-2026-123864は、HTTPSにおける再入(リエントラント)の欠陥です。on_bodyコールバック内で長さゼロの書き込みが発行されると、TLSWrap::DoWrite()がClearOut()を呼び出します。その結果、llhttp_execute()がボディ処理の途中で再入します。

この結果、use-after-freeとヒープの境界外読み取りが発生し、TLS秘密鍵や他のユーザーのリクエストが漏えいするおそれがあります。平文のnode:httpは影響を受けません。

CVE-2026-123866では、バックプレッシャー中に、たとえばRST_STREAMやストリームごとのタイムアウトなどでストリームが破棄されると、解放済みのレスポンスバッファのメモリがピアに送信されます。

ファイル配信ハンドラーには、ヒープ破壊とNULLポインタ参照の問題があります。CVE-2026-123874では、キューに入った書き込みがまだ参照しているHttp2Streamが解放され、その後、宙吊り状態のオブジェクトを介して仮想呼び出しが行われます。

アプリケーションがrespondWithFile()またはrespondWithFD()を使用していると、常にこの問題が発生します。CVE-2026-123875はStreamPipeのNULL参照で、ダウンロードを数回キャンセルするだけで引き起こされる可能性があります。

CVE-2026-123828はsession.altsvc()における1バイトのヒープバッファオーバーフローです。アプリケーションが攻撃者の制御する:authorityヘッダーを渡した場合に到達可能となります。

このオーバーフローは、リモートからヒープ破壊を引き起こす攻撃手段となります。この種のuse-after-free状態は、コード実行へと連鎖的に悪用されることが多いものの、Node.jsはここでの影響をクラッシュ、メモリ漏えい、メモリ破壊のみと記載しています。

リソース枯渇とプロセス終了の問題は、HTTP/2のフレーム処理だけにとどまりません。CVE-2026-123868は会計処理上の欠陥を突くもので、キューに入った受信データがどのセッション予算にも計上されません。

攻撃者が1バイトのデータフレームごとに支払うワイヤ上のコストは約10バイトですが、サーバーは約114バイトを保持し続けます。そのため、maxSessionMemoryでは増加を抑えられず、新規ストリームの拒否もできません。

CVE-2026-126051では、SNIなしでOCSPリクエストを含むクライアントHelloを送り、続けてパディングとソケットのFINを送信すると、OpenSSLの遅延コールバックが実行される前にソケットが破棄されます。

その結果、プロセスで未処理の例外が発生します。CVE-2026-123862も同様の影響をもたらします。zlib.params()の後にdestroy()を呼び出すと、捕捉できないERR_INTERNAL_ASSERTIONが発生します。

Node.jsによると、認証と信頼境界に関する欠陥が3つ目のグループを形成しています。CVE-2026-123872では、クライアントがTLS 1.2の再ネゴシエーション中にservernameを変更し、認証情報をより厳格なホストに引き継ぐことができます。

CVE-2026-123867は、サーバー証明書がない状態でのserver.addContext(host, { ca })に関するものです。setSniContextがfalseを返すため、ハンドシェイクは何も通知しないままデフォルトのクライアントCAを使い続け、ホストごとのmTLSを回避してしまいます。

CVE-2026-123877では、caの省略とca: []が同じキャッシュキーを共有するため、https.AgentがポリシーをまたいでTLS 1.3セッションを再利用します。認証情報の取り扱いミスにも同様の注意が必要であり、ID情報や証明書の悪用は、引き続き防御側にとって優先課題です。

CVE-2026-123871は、ERR_PROXY_INVALID_CONFIGを通じてプロキシの認証情報を漏えいさせ、ログやクラッシュレポーターにまで到達します。深刻度Lowに分類されるPermission Modelの欠陥は、サンドボックスの保証を弱めます。

CVE-2026-123829では、macOSとWindows上で再帰的なfs.watch()を通じて、アクセスを拒否された下位ファイルの名前が漏えいします。CVE-2026-106071では、ワイルドカードのradix検索により、--allow-fs-readのパスに対して過剰な権限が付与されます。

報告者には、ClaudeおよびAnthropic Researchと協力したChris Rohlf氏、pimterry氏、Trail of Bitsが含まれます。修正はmcollina氏、RafaelGSS氏、jasnell氏が担当しました。

管理者は、直ちにv22.23.5、v24.22.3、またはv26.13.1へアップグレードすべきです。サポート終了(EOL)となったブランチは常に影響を受けますが、修正は提供されません。パッチを適用できない場合は、HTTP/2リスナーの公開範囲を制限し、respondWithFile()ハンドラーを見直し、ホストごとのmTLS設定を監査する必要があります。

ANY.RUNを活用する16,000以上のSOCチームに加わり、脅威調査を効率化して手作業を削減しましょう。チームで試してみる

翻訳元: https://cyberpress.org/node-js-fixes-16-security-flaws/

本記事は cyberpress.org の記事を翻訳・要約したものです。