Brotli CVE-2026-111497 (Node2Shell / HTTP2Shell): 影響を受けるバージョン、修正済みリリース、および回避策

CVE-2026-111497 で何が起きたか

CVE-2026-111497 は、Google の Brotli デコーダーにおける重大な領域外書き込みで、Brotli バージョン 1.0.3 から 1.2.0 のすべてのプラットフォームに存在します。Node.js は 2026 年 10 月 21 日の週にこれを「Node2Shell」として開示し、セキュリティ研究者が Python パッケージ、ネイティブ libbrotli、curl、Bun、Envoy、Istio、Git for Windows、および Brotli デコーダーをバンドルする多くのアプリケーションに同じデコーダーバグが影響することを確認したため、「HTTP2Shell」に名称が拡大されました。修正は Brotli 1.2.1(およびバックポート 1.0.10 と 1.1.1)で提供され、脆弱な Brotli デコーダーを静的にリンクまたはバンドルするライブラリやアプリケーションは、それぞれ独自のリリースが必要です。

Aikido は 2026 年 10 月 23 日に集約アドバイザリを公開し、パッチがエコシステム全体にまだ展開されており、ベンダーが影響を受けるコンポーネントを順次発表していることを指摘しました。

技術的な根本原因: DecodeBlockTypeAndLength() のあいまいなブール値

この欠陥は、ブロックスイッチを処理する Brotli デコーダー関数 DecodeBlockTypeAndLength() にあります。ブロックスイッチは、Brotli ストリームが使用するハフマンツリーを変更するポイントです。脆弱なバージョンでは、この関数は単純なブール値を返すため、BROTLI_FALSE は「このストリームは不正」または「さらに入力が必要」のどちらかを意味する可能性があります。呼び出し側はこの 2 つのケースを区別できず、高速デコードパスではデコーダーは戻り値を完全に破棄します。

巧妙に細工されたストリームは、単一のブロックタイプを宣言し、そのブロックの長さを使い切って、成功しないブロックスイッチを強制できます。デコーダーは、実際には完了しているストリームに対してさらに入力が必要であると報告するか、既存のブロック状態でデコードを続行します。この 2 番目のパスで領域外書き込みが発生します。

上流の修正である google/brotli コミット 0ed4268 は、関数がエラーコードを返すようにし、新しいエラー値 BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17) を導入します。デコードは、セーフパスと高速パスの両方でフォーマットエラーで停止するようになりました。Brotli 1.2.0 と 1.2.1 のソース配布の差分分析により、1.2.1 はバージョン番号の変更と、そのコミットによるデコーダーの変更のみが異なることがわかりました。

CVE レコードは、CWE-252(チェックされていない戻り値)と CWE-787(領域外書き込み)をペアにし、CVSS v4.0 スコア 9.2(重大)を割り当てています。

攻撃の影響: メモリリーク、クラッシュ、または双方向のリモートコード実行

CVE-2026-111497 により、リモートの認証されていない攻撃者が、メモリを破損させ、機密データを漏えいさせ、プロセスをクラッシュさせ、または任意のコード実行を達成する可能性のある、巧妙に細工された Brotli 圧縮ストリームを送信できます。この欠陥は、双方向で機能する認証されていないリモートコード実行として報告されました。つまり、悪意のあるクライアントがパッチ未適用のサーバーを乗っ取ることができ、悪意のあるサーバーが圧縮応答を受け入れるパッチ未適用のクライアントを乗っ取ることができます。

デコーダーを公開する 2 つのデータパスがあります:

  • 送信リクエスト。 アプリケーションが、攻撃者が制御するサーバーから Brotli エンコードされた応答を取得します。たとえば、Webhook 配信、URL プレビュー、クローラー、または「この URL を取得」機能などを介して取得します。
  • 受信リクエスト。 フレームワークまたはミドルウェアが、Content-Encoding: br で送信されたリクエストボディをデコードします。これは、Node.js の Express 5 のケースに相当する Python です。

The Hacker News は、2026 年 10 月 22 日時点で実際の悪用は報告されていないと報じました。

CVE-2026-111497 の修正済みバージョン

Brotli をバンドルするすべてのプロジェクトは、独自のアップデートを提供する必要があります。根本原因はソースコードで上流修正されましたが、これまで修正を含む上流リリースは出荷されていなかったためです。2026 年 10 月 23 日に確認された修正済みリリース:

プロジェクト パッチステータス 修正済みバージョン メモ
Node.js パッチ利用可能 22.23.4, 24.22.1, 26.12.1 サポートされているリリースラインを使用
Bun パッチ利用可能 1.4.4 Brotli 1.2.1 を含む
Envoy パッチ利用可能 1.40.0, 1.39.3, 1.38.6, 1.37.8 1.36.12 にも修正が含まれていますが、1.36 はサポートされていません
Istio パッチ利用可能 1.29.9, 1.30.6, 1.31.2 1.29 はサポート終了です。サポートされているラインに移行してください
Google Brotli (上流) パッチ利用可能 1.0.10, 1.1.1, 1.2.1 対応するライブラリブランチに一致する修正済みリリースを選択
Python: Brotli (PyPI) パッチ利用可能 1.2.1 リリースノートに CVE の記載はありません
Python: brotlicffi (PyPI) パッチ利用可能 1.2.1.0 リリースノートに CVE の記載はありません

アドバイザリからの追加のガイダンス:

  • curl / libcurl: Brotli 依存関係を 1.2.1、パッチ適用済みの古いリリース、またはベンダーのセキュリティ修正済みパッケージに更新します。バンドルまたは静的にリンクされたコピーには、更新されたアプリケーションビルドが必要です。
  • オペレーティングシステムパッケージ: ベンダーのセキュリティアップデートをインストールします。ベンダーは上流のバージョン番号を変更せずに修正をバックポートする場合があります。
  • その他の HTTP サーバー、リバースプロキシ、API ゲートウェイ、HTTP クライアント: 影響を受けるランタイムまたは使用する Brotli ライブラリを更新します。Brotli が製品にバンドルされている場合は、この CVE に明示的に対処する製品ベンダーのリリースをインストールします。マネージドサービスの場合は、プロバイダーに修復を確認してください。

アップグレード後、依存関係ロックを更新し、影響を受けるアプリケーションとコンテナイメージを再ビルドし、再デプロイしてサービスを再起動し、実行中のワークロードがパッチ適用済みコンポーネントを使用していることを確認します。

1 つの Brotli バグがこれほど多くの言語と製品に影響する理由

Python、Node.js、C++、libbrotli、Envoy、Bun はすべて、同じ C Brotli デコーダーをコンパイルまたはバンドルしているため影響を受けます。デコードロジックの実装は 1 つしかないため、単一のメモリ安全性の欠陥が、それを埋め込むすべてのランタイムに伝播します。

2 つの PyPI パッケージ、Brotli と brotlicffi は、Node.js がバンドルしているのと同じ脆弱なデコーダーをコンパイルしており、Brotli は月間 8,280 万ダウンロードされています。urllib3(したがって requests)、brotli エクストラ付きの httpx、aiohttp などの HTTP クライアントは、存在する場合にいずれかのパッケージを自動的にロードし、アプリケーションが Brotli を直接インポートしなくても Brotli 応答をデコードします。Scrapy やその他のパッケージは、依存関係として Brotli をインストールします。その結果、Python アプリケーションは、独自のソースコードに Brotli インポートが 1 つも含まれていなくても、露出する可能性があります。

一部のコンポーネントはデコードパスに対して脆弱ではありません。Apache の標準の mod_brotli は Brotli をデコードせず、Apache と Nginx はデフォルトで Brotli をデコードしません。

アドバイザリデータベースのギャップ: pip-audit、Dependabot、Safety はまだフラグを立てていません

2026 年 10 月 23 日時点で、アドバイザリデータベースは CVE-2026-111497 を Brotli または brotlicffi PyPI パッケージのいずれにもマッピングしていませんでした。CVE レコード、OSV、GitHub Advisory Database は 2 つのパッケージをリストしておらず、pip-audit、Dependabot、Safety が脆弱なバージョンをフラグ付けしないことを意味します。GitHub アドバイザリが GHSA-9v8h-qqgm-4m35 に投稿され、報告者は PYSEC エントリと GitHub アドバイザリの PyPI パッケージマッピングを提出して、ツールがそれを拾えるようにしていました。そのマッピングが公開されるまで、露出チェックは手動で行う必要があります。

アプリケーションが露出しているかどうかを確認する方法

脆弱な Brotli デコーダーのインストール済みコピーは、アプリケーションコードがそれを呼び出さなくても、露出するのに十分です。実用的なチェック:

  1. 各環境で pip show Brotli brotlicffi を使用してインストール済みバージョンを確認し、各コンテナイメージで docker run --rm <image> pip show Brotli brotlicffi を使用します。
  2. パッケージを引き込むものを特定します。pipdeptree -r -p Brotli を実行して、どの依存関係がそれを必要とするかを確認し、grep -i brotli poetry.lock uv.lock requirements*.txt でロックファイルを検索します。
  3. 制御していないサーバーへの送信 HTTP 呼び出しと、Content-Encoding: br リクエストボディをデコードするエンドポイントをリストします。
  4. 手順 3 に一致するサービスを最初にアップグレードし、次に残りをアップグレードします。

再現作業の場合: brotli.decompress() は、あらゆるエラーに対して一般的な brotli.error: decoder failed を発生させるため、特定のエラーコードは Python からは見えません。細工されたストリームを段階的に供給された Decompressor() は、1.2.0 では決して完了しません。AddressSanitizer でビルドされた Brotli 1.2.0 と 1.2.1 をテストしたところ、1.2.0 は約 23 MB の細工されたストリームをすべて消費し、ストリームが 1 つのまとまりで到着したか、1 バイトのチャンクで到着したかに関係なく、さらに入力が必要であると繰り返し報告しました。バージョン 1.2.1 は、毎回エラー -17 でストリームを拒否しました。

すぐにアップグレードできない場合の回避策

これらの緩和策は、パッチが準備されている間の露出を減らします:

  • Python アプリケーション: Brotli サポートがオプションの場合は、影響を受ける環境から Brotli と brotlicffi の両方をアンインストールします。httpx[brotli] などの依存関係エクストラと、それらを再インストールするその他の要件を削除し、依存関係ロックを再生成して、ワークロードを再ビルドまたは再起動します。httpx、requests、urllib3 は、オプションのパッケージなしで gzip と deflate のサポートを維持しますが、それでも Brotli を送信するサーバーは、読み取り不能な応答またはアプリケーションエラーを生成する可能性があり、自動フォールバックは保証されません。
  • 受信 HTTP リクエスト: リバースプロキシ、ロードバランサー、またはアプリケーションミドルウェアで、脆弱なデコーダーがボディを処理する前に、Content-Encoding に br が含まれるリクエストを拒否します。br を大文字と小文字を区別せずに一致させ、エンコーディングのリスト内に表示される場合も含めます。
  • 送信 HTTP リクエスト: Accept-Encoding から br を削除し、Brotli 応答デコードを無効にするか、デコードを開始する前に Content-Encoding に br が含まれる応答を拒否します。チェックは自動ボディ処理の前に行う必要があります。クライアントが応答をダウンロードしてデコードした後にチェックするのは遅すぎます。

Accept-Encoding を変更するだけでは不十分です。悪意のあるサーバーは、クライアントがアドバタイズする内容に関係なく Brotli 応答を送信でき、urllib3 は応答の Content-Encoding ヘッダーからデコーダーを選択するためです。Python パッケージをアンインストールしても、他のランタイム、ライブラリ、または製品にバンドルされている個別の Brotli デコーダーは削除されません。

開示のタイムラインと OpenAI の 2 月の発見

Aikido の TL;DR は、Node.js が 2026 年 10 月 21 日水曜日に CVE-2026-111497 を開示したと述べていますが、同じアドバイザリの後のタイムラインセクションでは、Node.js の開示は 2026 年 10 月 22 日水曜日と説明されています。ソースには両方の日付がリストされています。Python は翌日、同じ欠陥を修正するセキュリティアップデートを公開しました。10 月 23 日金曜日、この CVE が HTTP を使用する他の主要な言語とサービスアプリケーションに影響し、パッチがまだ完全には利用できないことが明らかになりました。

OpenAI は、2 月にこの脆弱性を発見したと述べました。根本原因はその時点で Brotli ソースコードで修正されましたが、セキュリティ問題として認識されず、2026 年 10 月まで修正を含むリリースは出荷されませんでした。OpenAI はこれを双方向で機能する認証されていないリモートコード実行として報告し、patchtheplanet.org/brotli で参照されるアドバイザリを公開しました。

Hacker News のコメント投稿者は、帰属に反発しました。あるコメント投稿者は、2 月の変更は OpenAI ではなく Google からのものであると主張しました:

記事は OpenAI が 2 月にこれを見つけたと主張していますが、それは正しくないと思います。Google が 2 月に Brotli ソースコードに問題を修正する変更を加えたが、それがセキュリティ問題であることに気づかず、リリースを切っていなかったのだと思います。

別のコメント投稿者は、重大度の報告とリリースの出荷の間のギャップを強調しました:

双方向で機能する認証されていないリモートコード実行として報告されましたが、当時はセキュリティ問題として認識されておらず、修正を含むリリースは今まで出荷されていませんでした。私はいつも危険な RCE バグと無害な RCE バグを混同しています。2 月にこれがどのように報告され修正されたのに、誰も重要性を認識しなかったのか興味があります。AI 自動化のケースで、誰もハンドルを握っていなかったのでしょうか?

コミュニティの反応: 命名、複雑さ、C 言語の議論

Hacker News の議論で最も一貫した不満は名前でした。「Node2Shell」は、Python や他のエコシステムが影響を受けると確認された後、範囲を説明しなくなり、「HTTP2Shell」は広すぎて曖昧すぎると広く拒否されました:

まあ、HTTP2Shell という名前を選んだ人は、人工知能であれ本物の知能であれ、間違いなく知能を使っていません。それは非常に無意味で、広範で、実際の問題を説明していません。おそらく、背後に何もない HTTP サーバーには影響しないでしょう。なぜ HTTP が非難されているのですか?

スレッドで提案された代替名には、Brotli2Shell と Broccoli2Shell が含まれていました。あるコメント投稿者は、HTTP はバグに付随するものにすぎないと主張しました:

同じ脆弱性に対して Broccoli2Shell の名前とサイトの方がずっと好きです。まず、手動の Brotli デコードを行えば、HTTP なしでこれに遭遇できると確信しています。HTTP はたまたま最も一般的なケースにすぎません。

何人かのコメント投稿者は、Brotli 圧縮された リクエスト ボディがデフォルト構成で実際にどれだけ広くデコードされているかを疑問視し、アドバイザリが通常の応答解凍とより曖昧なインバウンドパスの違いを曖昧にしていると主張しました:

私にとって驚くべきことは、これほど多くの実装がリクエスト(応答だけでなく)ボディの brotli 圧縮を実装していることです。これは非常に曖昧な機能です。いずれにせよ、このセンセーショナリズムはうんざりし始めています。パッチを当てて先に進みましょう。

複雑さの議論も浮上し、gzip/deflate を置き換えるコストとしてフレーム化されました:

複雑さが増すコストの例だと思います。Brotli は、置き換える gzip/deflate よりもはるかに複雑です。...そしてもちろん、gzip も攻撃にさらさなければなりません。何かを追加するたびに何かを失います...

1 つのスレッドは、これが C に対する議論であるかどうかを中心に展開しました:

正直、セキュリティが重要な場所で使用される言語として C を廃止する時が来ました。もう十分です。一般的なインターネットトラフィックを処理し、Google が保守している brotli のようなライブラリが、なぜ rust でないのですか?

上流パッチのレビュアーは、それが急いでいると感じました:

C コードのパッチも読みました(ちなみに、isSafe メソッドなどが追加されていて、私には少しハッキーに見えます...このパッチは本当に「バッファオーバーフローする C の豚に口紅を塗る」ように見えます)。... Python / Node / C++ / libbrotli / Envoy / Bun の間のリンクは何ですか: これらはすべて同じ C brotli エンコーダー/デコーダーを使用していますか?

そのコメント投稿者の質問への答えはイエスです: それらはすべて同じ Brotli C デコーダーを埋め込むかリンクしているため、上流の Brotli 1.2.1 だけでは、独自のコピーをバンドルするシステムを保護できません。

コメント投稿者によって報告された運用上の影響を受けるソフトウェア

コメント投稿者は、アドバイザリの表を超えた実際の露出をカタログ化しました:

  • Git for Windows は、最新リリース(2.56.0.windows.3)でも脆弱です。修正はリポジトリにマージされていますが、スナップショットビルドでのみ利用可能で、フォローアップリリースは月曜日(2.56.0.windows.4)に予定されています。信頼できないサーバーから HTTPS 経由でリポジトリをプルすることが関連するリスクです。
  • Codex(GUI)は独自の Git と独自の Node を同梱しており、コメント投稿者は潜在的にリスクが高いと説明しました。提案された緩和策は、Codex を更新し、~/.cache/codex-runtimes のキャッシュをクリアすることです。
  • Wireshark と ImHex は、最新のリポジトリコミットでも脆弱なままです。
  • Microsoft 365 Copilot は、10 月 7 日付けの独自のパッチ未適用の brotlidec.dll をまだ出荷しており、修正は利用できず、脆弱なデコーダーに到達する確認された経路もありません。
  • Ubuntu はまだ libbrotli1 パッチを中程度の重大度の項目としてレビュー中であり、libcurl の更新、ひいては Git やその他の依存パッケージの更新を保留していました。
  • 単一の Windows 開発ボックスでのファイル検索で、Brotli ライブラリが Git、Sublime Text、Visual Studio、CUDA、.NET、Inkscape、Azure Tools にリンクされていることがわかりました。

運用側のコメント投稿者の 1 人は、フリートをチェックし、露出がまったくないことを確認し、推移的依存関係の宝くじを示しました:

すべての Python デプロイメントとインストール BOM を確認する必要があり、かなり安心しました。実際には brotli ライブラリをインストールしていないことが判明しました。httpx、requests、フレームワークなどの HTTP ライブラリはそれらをオプションと見なし、存在を自動検出します。

スレッドで提起された未回答のアーキテクチャ上の質問は、ロードバランサーが TLS を終了し、解凍を処理する場合にアプリケーションが安全かどうかでした:

TLS を終了する Amazon Elastic Load Balancer の背後に node.js アプリがあるとします。私の理解では、ほぼすべての構成で、ELB が解凍を処理するため、アプリは影響を受けないでしょう。これは一般的に正しいですか?

議論には決定的な回答は記録されていないため、実用的なルールは変わりません: エッジプロキシがリスクを排除すると想定するのではなく、デコードパス内のすべてのコンポーネントを監査します。

パッチ速度の問題

議論はまた、依存関係管理におけるより広い緊張を捉えました。パッケージエコシステムは 2025 年を通じて、サプライチェーン攻撃を回避するために新しく公開されたリリースにクールダウンを適用するようエンジニアにアドバイスしていましたが、重大な脆弱性により現在はそれらのクールダウンを脇に置くことを余儀なくされています:

数か月前、誰もがパッケージアップグレードでクールダウンを使用するようにアドバイスしていました。現在、セキュリティインシデントはすぐに悪用されるため、常にそれを上書きしています。今後はそうなる運命だと思います。

一部のエンジニアは修復を自動化することで対応し、あるコメント投稿者は新しいアドバイザリが表示されるたびに Claude Code をそれに向けると説明しました。他の人は実用的な姿勢を率直に述べました: パッチを当て、再ビルドし、再デプロイし、先に進みます。スレッドが論争しなかった点は、Brotli デコーダーが現在、ほぼすべての HTTP クライアントとサーバーの信頼できない入力攻撃面の一部であり、Brotli をバンドルするすべてのプロジェクトが CVE-2026-111497 に対して独自のアップデートを出荷する必要があるということです。

Sources

関連

  • Dispatch
  • プロジェクト
  • プロジェクト
  • Dispatch
  • Dispatch