Brotli RCE(CVE-2026-111497)は、Node.js の node2shell として広まり、正体は上流の Brotli ライブラリ(google/brotli)にあると分かってきました。ただ、Brotli をデコードするのはアプリだけではありません。Envoy Proxy と、そのデータプレーンを使う Istio(サービスメッシュ)も、Brotli デコンプレッサを構成していれば同じデコーダを通ります。この記事は、既報(Node 同梱・上流 Brotli・PyPI)で手薄だったプロキシ/サービスメッシュ層に焦点を当て、上流から Node・Envoy・Istio までを1枚にしたクロススタックのパッチ適用表と、経路別の緩和を、各社の公式アドバイザリで裏を取って整理します。依存する部品の問題が横へ広がる構図は、関連記事のサプライチェーン攻撃とは|手口・防御ツール比較・npm 12の新機構まで実践解説でも扱いました。

WHERE BROTLI DECODESBrotliが展開される所

攻撃者の Brotli を展開する所すべてが射程

  1. HTTPクライアント

    fetch・curl が応答の Brotli を展開

  2. Webサービス

    Express・Koa が要求ボディを展開

  3. プロキシ / メッシュ

    Envoy・Istio が要求/応答を展開

  4. ファイル処理

    信頼できない .br を展開

出典: Node.js・Envoy・Istio 各公式アドバイザリ(2026-10-25 確認)。素のサーバーは受信 Brotli を自動展開しない

30秒でわかる ・CVE-2026-111497 は上流 google/brotli のデコーダの境界外書き込み。Brotli を展開するアプリ・HTTPクライアント・プロキシ/サービスメッシュが対象
・Envoy は Brotli デコンプレッサを構成した場合に影響(GHSA-3wvj-j6qm-62mr・CVSS v4 9.2・Critical)。Istio はそのデータプレーンなので、Brotli 展開を有効化していれば同じく影響(ISTIO-SECURITY-2026-007)
・結果は条件により、クラッシュ・メモリ開示・コード実行。多くはクラッシュで、コード実行は構成と入力の条件がそろったときに限られる
・直し方は層ごとに修正版へ:上流 1.0.10 / 1.1.1 / 1.2.1、Node 22.23.4 / 24.22.1 / 26.12.1、Envoy 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 / 1.36.12、Istio 1.31.2 / 1.30.6 / 1.29.9

まずやること ・自分で直す範囲:アプリの Node.js・Bun、自前の Envoy/Istio を修正版へ上げ、上げ切るまで Brotli の展開を経路ごとに止める
・事業者・配布元に任せる範囲:マネージドのサービスメッシュ・API ゲートウェイ・CDN は、提供元の更新告知を確認する
・止めるのは Brotli の展開だけ。gzip/deflate は有効のままでよい

Brotli RCE(CVE-2026-111497)の時系列:どこまで広がったか

同じ CVE を、各プロジェクトが自らのアドバイザリで順に修正しました。日付はいずれも各プロジェクトの公表ページに記されたものです。

・2026-10-15:Istio が ISTIO-SECURITY-2026-007 を公表。「Envoy が使う Brotli 圧縮ライブラリの脆弱性」として 1.31.2 / 1.30.6 / 1.29.9 で修正
・2026-10-21:Node.js が10月のセキュリティリリース。同梱 Brotli デコーダの境界外書き込み(High)を 22.23.4 / 24.22.1 / 26.12.1 で修正。報告は OpenAI Codex Security の Khai Tran・Sylvie Mayer、修正は mcollina・aduh95
・2026-10-23:Envoy が GHSA-3wvj-j6qm-62mr(Critical・CVSS v4 9.2)を公表。Brotli デコンプレッサを構成した Envoy を 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 / 1.36.12 で修正

根っこは1つです。上流 google/brotli(1.0.3〜1.2.0 が影響範囲、修正は 1.0.10 / 1.1.1 / 1.2.1)のデコーダにある境界外書き込みを、Node・Bun・Envoy がそれぞれ同梱しているため、各プロジェクトが自分の取り込み分を個別に直しています。Node 側の詳細はNode2shell(CVE-2026-111497)|Node.js同梱Brotliデコーダの境界外書き込みRCEと直し方に、上流が正体で HTTP ライブラリ全般に及ぶ構図はHTTP2Shell とは|node2shellの正体は上流Brotliの問題にまとめています。

Envoy・Istio でも Brotli はデコードされる:サービスメッシュまでが射程

Envoy には Brotli デコンプレッサ・フィルタ(envoy.filters.http.decompressor の Brotli)があり、要求または応答の経路に置くと、受け取った Brotli を展開します。その展開に使うのが、今回の境界外書き込みを抱えたデコーダです。Istio のデータプレーンは Envoy そのもの(サイドカーとゲートウェイ)なので、EnvoyFilter などで Brotli 展開を有効にしていれば、同じデコーダを同じ条件で通ります。

ここで条件を外さないことが大事です。素の構成では、Envoy は受け取った Brotli を自動展開しません。影響するのは、Brotli デコンプレッサを構成しているEnvoy と、Brotli 展開を有効化しているIstio だけです。構成していない環境は、この経路の対象ではありません。影響の中身も、Envoy のアドバイザリは「情報開示・サービス拒否・条件によってはコード実行に至りうる」と記しており、常にコード実行になるわけではありません。

防御の設計として、「攻撃者が何を制御できるか × どこで展開されるか」を押さえます。

攻撃者が制御できる Brotli 展開する所 起こりうること
圧縮した要求ボディ(Content-Encoding: br) ingress の Envoy/Istio・アプリのボディパーサ デコーダのメモリ破壊 → クラッシュ・メモリ開示・条件つきコード実行
信頼できない上流からの Brotli 応答 応答を展開する Envoy・fetch・curl 同上
細工した .br ファイル ファイルを展開するアプリ 同上

クロススタックのパッチ適用表:上流Brotliから Node・Envoy・Istio まで

直す対象は「同梱している Brotli」です。どれか1つを直せば全部安全になるのではなく、Brotli を同梱する各コンシューマが、それぞれ修正版へ上がって初めて塞がります。

CROSS-STACK FIX MAPどの層を上げるか

上流 Brotli から Node・Envoy・Istio まで層ごとに上げる

  1. 上流

    google/brotli(本体)

    修正 1.0.10 / 1.1.1 / 1.2.1

  2. ランタイム

    Node.js(同梱)

    修正 22.23.4 / 24.22.1 / 26.12.1

  3. プロキシ

    Envoy(Brotliフィルタ構成時)

    修正 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 / 1.36.12

  4. メッシュ

    Istio(Brotli展開を有効化時)

    修正 1.31.2 / 1.30.6 / 1.29.9

出典: Node.js 10月セキュリティリリース・Envoy GHSA-3wvj-j6qm-62mr・ISTIO-SECURITY-2026-007(2026-10-25 確認)
プロジェクト 影響する条件 修正版 備考
google/brotli(上流) 1.0.3〜1.2.0 を同梱 1.0.10 / 1.1.1 / 1.2.1 各コンシューマが取り込む本体
Node.js(同梱 Brotli) fetch 応答・Express 5/body-parser 等で展開 22.23.4 / 24.22.1 / 26.12.1 20系以前は EOL。別の brotli ライブラリを上げても同梱分は変わらない
Bun(同梱 Brotli) HTTP で Brotli を展開 同梱 Brotli を修正版にしたリリースへ 具体の修正版は配布元の告知で確認
Envoy Proxy Brotli デコンプレッサ・フィルタを構成時 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 / 1.36.12 構成していなければこの経路の対象外
Istio(データプレーン=Envoy) Brotli 展開を有効化時(例:EnvoyFilter) 1.31.2 / 1.30.6 / 1.29.9 修正版は新しい Envoy を同梱
curl 等のHTTPクライアント --compressed 等で Brotli 応答を展開 同梱/リンクした Brotli を修正版へ ディストリの更新に従う

Bun と curl は内部に Brotli を同梱/リンクするため、具体の修正版は配布元のリリース告知で確かめます。注意点として、npm にある brotli という名前の純 JavaScript パッケージは今回の脆弱な部品ではなく、それを上げてもランタイムが同梱する上流 Brotli は変わりません。

自分の環境を確認する:Node・Bun・Envoy・Istio の版と Brotli フィルタ

確認は、版の比較と、Brotli 展開を構成しているかの2つに分けます。これは判定ではなく構成の確認で、見出しのとおり「確認」どまりです。

# 同梱 Brotli ランタイム:Node は本体の版で決まる(修正 22.23.4 / 24.22.1 / 26.12.1 以上)
node --version
node -p "process.versions.brotli"   # Node が同梱する上流 Brotli の版(1.0.10 / 1.1.1 / 1.2.1 以上なら対応済み)
bun --version                        # Bun も同梱 Brotli を持つ。配布元の修正版と突き合わせる

# プロキシ/サービスメッシュの版(Istio 1.31.2 / 1.30.6 / 1.29.9 以上、Envoy 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 / 1.36.12 以上)
istioctl version
envoy --version
# Brotli デコンプレッサ・フィルタを構成に入れているか(入れていなければこの経路の対象ではない)
grep -rIn "brotli" --include="*.yaml" --include="*.yml" .

結果の読み方には限界があります。陽性(Brotli が見つかる・版が古い)でも、該当フィルタを無効化済みなら実害が無い場合があり、陰性(見つからない)でも、テンプレートや上流で動的に Brotli を有効化していれば見落とします。node -p が見せるのは「Node が同梱する上流 Brotli の版」で、アプリが別経路で Brotli を展開していないかまでは分かりません。最終的な安全は、各層を修正版へ上げ切り、要らない Brotli 展開を無効化したことで確かめます。

経路別の緩和プレイブック:ingress・fetch・Envoy/Istio・再デプロイ

上げ切るまでの緩和は、どの経路でも原則が同じです。デコードする前に Brotli を拒否すること。経路ごとに置き場所が違うだけです。

PER-PATH MITIGATION経路別の緩和

デコードの前に Brotli を拒否し、直したら再デプロイ

  1. 1.ingress で拒否

    展開前に Content-Encoding: br の要求を弾く

  2. 2.fetch 応答で無効化

    クライアントの Brotli 自動展開を切る(Accept-Encoding だけでは不十分)

  3. 3.Envoy/Istio フィルタを外す

    要求・応答の Brotli 展開を無効化し下流も保護

  4. 4.ピン更新して再デプロイ

    修正版へ固定し全レプリカを再起動

出典: 各公式アドバイザリの緩和(2026-10-25 確認)。gzip/deflate は有効のままでよい。WAF・サイズ制限だけでは全経路を覆えない

・ingress:プロキシ・ミドルウェア・ボディパーサが展開する前に、Content-Encoding: br の要求を拒否する
・fetch 応答:HTTP クライアントの Brotli 自動展開を無効化する。Accept-Encoding から br を外すだけでは不十分で、サーバーが送ってくれば展開されうる
・Envoy/Istio:要求・応答の両方で Brotli デコンプレッサ・フィルタを無効化する。無効化すると圧縮データがそのまま下流へ渡りうるので、下流のデコーダも同じ基準で保護する
・ファイル:パッチが当たるまで、信頼できない Brotli ファイルの処理を一時停止する
・再デプロイ:ランタイムとイメージのピンを修正版へ更新し、全サービス・ワーカー・ジョブ・レプリカを再起動して、動いている版が修正版かを突き合わせる

誤解しやすい点を2つ。CDN や Web サーバーで Brotli の「レスポンス圧縮」を切っても、要求側・クライアント側の展開は止まりません。また、WAF ルールやサイズ制限だけでは、すべてのデコード経路は覆えません。フレームワークごとの運用指針としては、Express は Brotli の要求を拒否して gzip/deflate は残す、Next.js は Node にパッチが当たるまで組み込みの画像最適化を無効化する、Python の HTTP クライアントは gzip/deflate を受理して Brotli を拒否する、といった形になりますが、具体の設定は各公式ドキュメントに従ってください。

影響範囲:攻撃者が制御できる Brotli をデコードする所すべて

対象は、修正前のバージョンで、攻撃者が内容に影響できる Brotli(圧縮した要求ボディ・信頼できない応答・圧縮ファイル)をデコードするアプリ・プロキシ・サービスメッシュです。結果は多くがクラッシュで、コード実行は構成と入力の条件がそろったときに限られる、というのが各アドバイザリの読み方です。公表の範囲を超えて「どの環境でも必ずコード実行になる」とは言えません。

この CVE は、当サイトでも角度を変えて追ってきました。Node 同梱と fetch/Express 5 の露出経路はnode2shell の記事、上流 google/brotli が正体で HTTP ライブラリ全般に波及する構図はHTTP2Shell の記事、PyPI の brotli・brotlicffi と依存スキャナの盲点はPython/PyPIのBrotli脆弱性の記事にあります。本記事はその続きで、見落とされがちなプロキシ/サービスメッシュ層を足したものです。修正はどの層も「版を上げる」ことに尽きるので、構成に Brotli 展開があるなら、待つ理由はありません。

参照ソース

・Node.js — October 2026 Security Releases(CVE-2026-111497): https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
・Envoy — Out-of-Bounds Write in Brotli Decompressor(GHSA-3wvj-j6qm-62mr): https://github.com/envoyproxy/envoy/security/advisories/GHSA-3wvj-j6qm-62mr
・Istio — ISTIO-SECURITY-2026-007: https://istio.io/latest/news/security/istio-security-2026-007/
・google/brotli — Releases(上流の修正版): https://github.com/google/brotli/releases