Brotliの展開処理に見つかった脆弱性「CVE-2026-111497」に対し、Node.js、Bun、Envoyの修正版が公開された。Brotliはデータ圧縮方式の一つで、今回の問題は圧縮データを元に戻す「展開」の処理にある。不正な圧縮データを処理するとメモリが破壊され、条件によってはリモートコード実行(RCE)に至る可能性がある。攻撃の入口は外部から受け取るHTTP要求だけでなく、アプリケーションが外部サーバーから取得する応答にも及ぶため、公開サーバーへの通信を調べるだけでは不十分だ。10月23日に更新されたPatch the Planetの案内によると、対策には稼働中のランタイムだけでなく、それを組み込んだ配布アプリケーションや、プロキシの転送先まで確認する必要がある。

AD

不正な入力を「入力不足」と誤判定、8バイトのバッファを超えて書き込み

Node.jsのセキュリティ告知によると、脆弱性の原因は、データを少しずつ受け取りながら展開するストリーミングデコーダーのエラー処理にあった。本来は処理を中止すべき不正なブロック切り替えを、デコーダーが一時的な入力不足と誤って判断してしまう。その結果、8バイトの内部バッファにデータを追加し続け、確保されたメモリ領域を超えて書き込む「境界外書き込み」が発生する可能性がある。この問題によってプロセスのクラッシュやメモリ内の情報漏えいが起き、さらにはRCEにつながるおそれがあるという。

本来は不正な入力として拒否すべきデータを、追加の入力を待つ状態として扱ったことが、メモリ破壊につながる。重要なのは、今回の脆弱性が圧縮処理ではなく、圧縮されたデータを展開する処理に存在する点だ。アプリケーションが送信時にBrotliでデータを圧縮しているだけでは、脆弱性の影響を受けるとは限らない。外部から受け取った圧縮データを、どこで、どのように展開しているかを確認する必要がある。

Node.jsは26、24、22の各系列が影響を受けるとし、深刻度を「High」と評価している。発見者として挙げられているのは、OpenAI Codex SecurityのKhai Tran氏とSylvie Mayer氏だ。Brotli本体も2026年10月21日にバージョン1.2.1をセキュリティ修正版として公開しており、Node.jsも同日に修正版をリリースした。すでに修正は提供されており、現在の課題は脆弱な実装を使っている環境へ確実に適用することにある。

受信したHTTP要求だけでなく、外向きのfetchも攻撃経路に

外部から届いたHTTP要求の本文をアプリケーションやミドルウェアが展開する構成では、その要求が攻撃の入口になり得る。一方、アプリケーションが外部サーバーから取得した応答を展開する場合も、同じ脆弱な処理が呼び出される可能性がある。ただし、HTTPサーバーを公開しているだけで直ちに影響を受けるわけではない。問題となるのは、攻撃者が用意したBrotli圧縮データが、脆弱なデコーダーに渡される経路が存在する場合だ。

Bunの公式アドバイザリーによると、外部データを取得するfetchは、Content-Encoding: brが指定されたHTTP応答を自動的に展開する。このヘッダーは、応答本文がBrotli形式で圧縮されていることを示すものだ。Bunはこのほか、node:zlibやDecompressionStreamも影響を受けるAPIとして挙げている。つまり、開発者が展開処理を明示的に実装していなくても、利用するAPIの内部で脆弱なデコーダーが動作する場合がある。

実際にコード実行が成立することを確認したのが、10月22日に検証結果を公開したImpervaだ。同社は、公式のNode.js 24.22.0を使用したLinux arm64環境で、外向きのfetchが受け取った応答と、展開処理を有効にしたExpress/body-parserが受け取るHTTP要求の両方から、コード実行に成功したと報告している。修正版の24.22.1では、同じ入力が拒否された。コード実行の実証にはデバッガーや計測用に改造したバイナリを使用しておらず、原因調査のために実施したメモリサニタイザーによる検証とは区別している。

ただし、Impervaの実証では、すべての試行でコード実行が成功したわけではない。Express/body-parserについても特定のバージョンと設定の組み合わせを検証した結果であり、対象範囲のすべての中間バージョンを個別に試したものではない。また、別のCPUアーキテクチャや、すべてのNode.jsビルドで同様の結果になるとは限らない。Bunも自プロジェクトでRCE攻撃を実証していないと明記しており、Node.jsでの成功をBunにもそのまま当てはめることはできない。これらは特定の検証環境で攻撃が成立したことを示す報告であり、実際の被害や攻撃者による悪用が確認されたことを意味するものではない。

AD

Node.js、Bun、Envoyの修正版と更新対象

Node.jsは22.23.4、24.22.1、26.12.1で脆弱性を修正し、Bunも1.4.4で修正済みのBrotli 1.2.1を取り込んだ。Envoyでも複数の系列に修正版が用意されている。ただし、製品によって修正を適用すべき場所や、影響を受ける条件は異なる。2026年10月24日時点の公式情報を整理すると、以下のようになる。

製品 公式修正版 更新対象と注意点
Node.js 22.23.4 / 24.22.1 / 26.12.1 稼働中のランタイムを更新する。コンテナーなどに組み込んでいる場合はイメージも再作成し、再配置後の実際のバージョンを確認する。
Bun 1.4.4 ランタイムに加え、bun build --compileで作成した実行ファイルも再ビルドする。配布済みの実行ファイルは、ホスト側のBunを更新しても修正されない。
Envoy 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 / 1.36.12 Brotli展開機能を有効にした環境が対象。フィルターを無効化する場合も、転送先で圧縮データを展開していないか確認する。1.36系列はサポート対象外。

Bunで特に注意が必要なのは、bun build --compileで作成した実行ファイルにBunのランタイム自体が組み込まれている点だ。開発環境や配布先のBunを更新しても、すでに作成した実行ファイルの内容は変わらない。公式アドバイザリーによると、影響を受けるのは1.0.21以上、1.4.4未満のバージョンであり、それらを使って作成した実行ファイルも再ビルドするまで脆弱な状態が続く。修正を完了するには、配布済みの実行ファイルも更新・交換しなければならない。

Envoyでは、Brotliの展開機能を有効にしていることが影響を受ける条件となる。展開フィルターを無効化すれば、その場所で脆弱なデコーダーが動作することは防げるが、圧縮されたデータを転送先のアプリケーションが展開する場合は、別途対策が必要だ。また、Patch the Planetは、修正版の1.36.12が公開されているものの、1.36系列自体はサポート対象外であると注意を促している。脆弱性が修正されているかどうかと、利用している系列が継続的にサポートされているかどうかは、別々に確認する必要がある。

バージョン番号の大小だけでは、安全性を判断できない場合もある。Bunのアドバイザリーによると、Brotli本体の影響範囲は1.0.3〜1.2.0だが、修正済みの1.0.10と1.1.1は例外となる。このように過去の系列へ修正が取り込まれている場合は、各製品の公式告知に基づいて判断する必要がある。また、深刻度の評価も製品によって異なり、Node.jsが「High」とする一方、Envoyは「Critical」、CVSS 4.0で9.2と評価している。上の表は各製品の更新対象を整理したものであり、すべての影響製品を網羅したものでも、製品間の危険性を同一条件で比較したものでもない。

更新までの暫定対策と、稼働環境への反映確認

外部サーバーから取得する応答への対策では、Accept-Encodingヘッダーからbrを除外することと、Brotliの自動展開を無効にすることを区別する必要がある。Accept-Encodingはクライアントが受け入れ可能な圧縮方式をサーバーへ伝えるヘッダーであり、brを指定しなくても、相手がBrotli形式の応答を返さない保証はない。Patch the Planetの案内では、取得した応答を展開前に拒否するか、自動展開そのものを止める対応を求めている。通信相手へ希望する圧縮方式を伝えるだけでは、脆弱なデコーダーにデータが渡る経路を完全には遮断できない。

Bunのfetchで指定できるdecompress: falseは、Accept-Encodingからbrを除外するとともに、応答の自動展開も停止する設定だ。ただし、この設定が適用されるのは指定したfetch要求だけであり、ほかのAPIによる展開処理まで停止するわけではない。Bunの公式アドバイザリーも、影響を受けるバージョンにはプロセス全体に適用できる回避策がないと説明している。CDN側で応答の圧縮を停止しても、受信要求や外向きの通信で行われる展開処理には対処できない。WAFやデータサイズの制限についても、それだけであらゆる攻撃経路を防げるとは限らず、暫定措置として扱う必要がある。

EnvoyやIstioでBrotliの展開フィルターを無効化・削除した場合、圧縮されたデータは展開されないまま下流へ転送される。その先のアプリケーションがBrotliを展開する構成なら、脆弱なデコーダーに不正なデータが届く可能性は残る。したがって、フィルターを停止しただけで対策が完了したと判断せず、転送先のデコーダーも確認する必要がある。HTTP要求と応答の両方向に加え、フィルターを通らずにデータが届く経路も調べ、外部からの圧縮データを安全に拒否できるかを確かめることが重要だ。

根本的な対策は、脆弱なBrotli実装を修正版に置き換えることにある。ランタイムやコンテナーイメージのバージョンを固定している場合は、その指定を修正版へ変更し、必要に応じてイメージや実行ファイルを再作成する。そのうえで、Webサービスだけでなくワーカーや定期実行ジョブも再起動・再配置し、すべてのレプリカに更新が反映されているか確認しなければならない。配布済みの実行ファイルと実際に稼働しているランタイムのバージョンを照合し、外部データを展開する経路に古い実装が残っていないことを確かめて初めて、対策が完了したと判断できる。