Node2Shell(CVE-2026-111497):Node.jsのBrotli RCE脆弱性と修正バージョン

Node2Shellは、Node.jsに同梱されているBrotliデコーダーの境界外書き込み(out-of-bounds write)脆弱性、CVE-2026-111497の通称です。細工されたBrotliストリームによって、Node.jsプロセスのクラッシュやメモリ内容の漏えいが起こり、構成によっては攻撃者のコードが実行される可能性があります。Node.jsは2026年10月21日にバージョン22.23.4、24.22.1、26.12.1でこの問題を修正し、発見者としてOpenAIのCodex Securityエージェントをクレジットしています。自分たちで管理していないBrotliデータを展開するサービスを運用しているなら、今すぐアップデートしてください。
問題があるのはNode.js自体のコードではなくGoogleのBrotliライブラリのため、Bun、Envoy、PythonのBrotliパッケージにもそれぞれ修正が必要になりました。リリースの翌日には、Impervaが改変されていない公式Node.jsイメージ上でコード実行に成功しています。
要点
- Node.jsの2026年10月セキュリティリリースによると、Node.js 22.23.4、24.22.1、26.12.1で修正されています。25.xや20.xなどのサポート終了(EOL)ラインには修正が提供されません。
- CVEを発行したGoogleは、CVEレコードでCVSS v4.0のスコアを9.2としています。Node.jsの評価はHighです。
- Node.jsは発見者を「OpenAI Codex Security (Khai Tran and Sylvie Mayer)」としてクレジットしています。EnvoyのアドバイザリではOpenAI Security Researchがクレジットされています。
- 公開されたPoC(概念実証)コードが存在します。ImpervaはLinux arm64版のNode.js 24.22.0でコード実行を達成しました。10月24日時点で、実環境での攻撃は確認されていません。
- 特に影響を受けやすいのは、信頼できないサーバーに対して
fetch()を呼び出すアプリ、body-parser 2を使うExpress 5、そして外部からの入力に対してnode:zlibのBrotli展開を行うあらゆるコードです。
Node2Shell(CVE-2026-111497)はどんな脆弱性か
CVE-2026-111497は、Google Brotliのバージョン1.0.3から1.2.0に含まれるBrotli展開器(c/dec/decode.c)のメモリ安全性に関する不具合です。CVEレコードはこれをバッファオーバーフローと説明しており、「リモートの認証されていない攻撃者」がデコーダーのメモリを破壊したり、メモリ内容を漏えいさせたり、サービス拒否を引き起こしたり、「あるいは細工されたBrotli圧縮ストリームを使って任意のコードを実行できる可能性がある」としています。
Brotliは、HTTPのContent-Encodingヘッダーでbrとして指定される圧縮形式です。ブラウザやCDN、サーバーで広く使われており、Node.jsはnode:zlibをサポートするためにデコーダーのコピーを独自に同梱しています。
Node.jsのアドバイザリは、根本原因を一文で説明しています。「不正なブロック切り替えが、恒久的なフォーマットエラーではなく一時的な入力不足として報告されたため、ストリーミングデコーダーが8バイトの内部バッファに入力バイトを追加し続けた」。平たく言えば、デコーダーは圧縮データ内のありえない命令に遭遇した際、それを「もっとバイトを待て」という意味だと取り違え、小さなバッファの末尾を越えて書き込み続けたということです。CVEレコードでは、CWE-787(境界外書き込み)とCWE-252(戻り値の未チェック)に分類されています。
Googleは10月21日、修正済みのBrotli 1.0.10、1.1.1、1.2.1をGitHubで公開しました。この修正により、デコーダーは当該の不正な遷移に対してフォーマットエラーを返すようになっています。
Node2Shellという名前の由来
この名前は、Impervaが10月22日に公開した調査記事「Node2Shell: From Brotli Data to Remote Code Execution」に由来します。PHP2Shellをはじめ、最近のリモートコード実行の脆弱性で使われている「〜2Shell」という命名にならったものです。「Shell」は攻撃者がサーバー上でコマンドシェルを取得できることを意味しますが、これまでに実証されたのは1つのテスト環境だけです。

影響を受けるバージョンと修正版
サポート中の22.x、24.x、26.xの各ラインでは、修正版より前のすべてのリリースが影響を受けます。サポート終了ラインもすべて影響を受けます。Node.jsは、セキュリティリリースの公開時にEOLバージョンは「常に影響を受ける」としているためです。
| 製品 | 脆弱なバージョン | 修正版 | 出典 |
|---|---|---|---|
| Node.js 26.x(Current) | 26.12.1より前 | 26.12.1 | Node.jsアドバイザリ |
| Node.js 24.x(LTS) | 24.22.1より前 | 24.22.1 | Node.jsアドバイザリ |
| Node.js 22.x(LTS) | 22.23.4より前 | 22.23.4 | Node.jsアドバイザリ |
| Node.js 25.x、20.x以前 | すべて | 修正なし(EOL) | Node.jsアドバイザリ |
| Google Brotli(Cライブラリ) | 1.0.3〜1.2.0 | 1.0.10、1.1.1、1.2.1 | CVEレコード |
| Bun | 1.4.3以前 | 1.4.4 | Bun v1.4.4リリースノート |
| Envoy(Brotliデコンプレッサーを設定している場合) | v1.39.2、v1.38.5、v1.37.7、v1.36.11 | v1.40.0、v1.39.3、v1.38.6、v1.37.8、v1.36.12 | GHSA-3wvj-j6qm-62mr |
Python Brotli / brotlicffi | 1.2.0以前 | 1.2.1 / 1.2.1.0 | PyPI: Brotli、PyPI: brotlicffi |
Debian brotliパッケージ | bookworm 1.0.9-2、trixie 1.1.0-2 | 1.0.9-2+deb12u1、1.1.0-2+deb13u1 | Debianセキュリティトラッカー |
npmにあるbrotliという名前のパッケージは無関係で、これを更新しても効果はありません。脆弱なコードはNode.jsランタイムのバイナリ内にあります。Debianは特殊なケースで、Debian独自のnodejsパッケージはシステムのBrotliライブラリにリンクしています。そのためDebianでは、新しいNode.jsのバージョン番号ではなくbrotliパッケージを通じて修正が届きます。
同じNode.jsのリリースでは、ほかに9件のCVEも修正されました。その中にはHighと評価されたものがさらに3件含まれます。DNS名の切り詰めの不具合(CVE-2026-105482)と、TLSのホスト名検証を回避できる2件の不具合(CVE-2026-105483、CVE-2026-106069)です。
実際に影響を受けるのは誰か
影響を受けるのは、攻撃者が手を加えられるBrotliのバイト列がデコーダーに届く場合です。脆弱なNode.jsバージョンを動かしているだけでは、その条件を満たしません。Node.jsのアドバイザリによると、「アプリケーションがnode:zlibで展開するBrotliデータを供給できる攻撃者」は、プロセスのメモリを破壊できます。実際には、そうしたデータは主に次の3つの経路で届きます。
- 外向きの
fetch():Node.js組み込みのfetch()は、Content-Encoding: brで送られたレスポンスをデコードします。ユーザーが指定したURLを取得するサービス(リンクプレビュー、Webhook、スクレイパー、Webを閲覧するAIエージェントなど)は、悪意のあるレスポンスを受け取る可能性があります。 - 内向きのリクエストボディ:body-parserのREADMEには、すべてのパーサーが「
gzip、br(brotli)、deflateの自動展開をサポートする」と書かれており、inflateオプションのデフォルトはtrueです。Express 5はbody-parser 2を使っているため、公開されているExpress 5のAPIはデフォルトでBrotliのボディをデコードします。Sysdigは、Koa(co-body経由)や@fastify/compressを使うFastifyも挙げています。 node:zlibの直接呼び出し:アップロードされたファイルやキューのメッセージに対してbrotliDecompress、brotliDecompressSync、createBrotliDecompressを実行するコードはすべて該当します。
自前のデータしか展開しない社内ツールは、優先度が下がります。それでもアップデートは必要です。サードパーティAPIのレスポンスなど、チームが見落としがちな場所からBrotliの入力が入ってくることがあるためです。
OpenAIのCodex Securityはどうやってバグを見つけたか
Node.jsは、この報告を「OpenAI Codex Security (Khai Tran and Sylvie Mayer)」の功績としています。Codex SecurityはOpenAIのアプリケーションセキュリティ向けエージェントで、コードベースの脆弱性を発見、検証、修正するためのツールとしてリサーチプレビューの形で公開されました。同じCVEに関するEnvoyのアドバイザリでは、「OpenAI Security Research」がクレジットされています。
Node.jsの修正が公開されたのは10月21日で、PHP2Shellの修正と同じ日でした。PHP2Shellも、AIを活用した監査によって古いバグが実際に動作するエクスプロイトに変わった事例です。どちらのケースでも、AIツールが広く共有されている古いCのコードを読み込み、そのコードを同梱していたすべてのプロジェクトがそれぞれ修正を出す必要がありました。同じ10月21日に起きたLiteLLMのサプライチェーン侵害は種類の異なる攻撃ですが、自分たちが把握していない依存関係という同じリスクを示しています。
タイムラインは短期間でした。
| 日付(2026年) | 出来事 |
|---|---|
| 10月16日 | GoogleがCVE-2026-111497を予約 |
| 10月21日 | GoogleがBrotli 1.0.10、1.1.1、1.2.1を公開。Node.jsが22.23.4、24.22.1、26.12.1をリリース |
| 10月22日 | CVEレコードが公開。最初の公開PoCが登場。Impervaがコード実行を報告。Bun 1.4.4、Python Brotli 1.2.1、brotlicffi 1.2.1.0がリリース |
| 10月23日 | EnvoyがGHSA-3wvj-j6qm-62mrを公開 |
| 10月24日 | Sysdigが実環境での悪用は確認されていないと報告 |
実際の危険度はどの程度か
プロセスをクラッシュさせるのは簡単ですが、コードを実行するのは困難です。ImpervaのRon Masas氏は、公式のNode.js 24.22.0 Linux arm64イメージ上で、取得したHTTPレスポンスとExpressのリクエストボディの両方の経路からコード実行に成功したと報告しています。一方で、「我々の環境では複数回の試行が必要だった」とも書いています。Impervaはエクスプロイトを公開しておらず、Node.js 24.22.1では同じ入力が拒否されました。
HeroDevsのサマリーによると、最初の公開PoCがコード実行に到達したのは、意図的に弱体化させたテストビルド上だけでした。標準ビルドでは、クラッシュと限定的なメモリ読み取りにとどまっています。Bun、Envoy、Pythonパッケージでのコード実行は、まだ誰も公には示していません。
クラッシュだけでも十分に痛手です。Node.jsのワーカーを落とす不正なリクエストが1つあれば、公開されているExpress 5のAPIに対して低コストのサービス拒否攻撃が成立します。また、メモリの漏えいによって、プロセスが保持しているトークンや鍵が露出するおそれもあります。
Node2Shellのパッチ適用と修正の確認方法
- ランタイムを22.23.4、24.22.1、26.12.1のいずれかにアップグレードします。これらはAPIの変更を含まないパッチリリースです。
- 実際に動いているものを確認します。Dockerfileを見るだけでなく、稼働中の各コンテナ内で
node --versionを実行してください。Sysdigは、キャッシュされたイメージから再ビルドするとnode:24のような浮動タグが古いビルドのまま残る可能性があると警告しています。再ビルドの前に、ベースイメージを改めてpullしてください。 - コンテナイメージ、サーバーレスのバンドル、CIランナー、シングル実行可能アプリケーションなど、Node.jsを組み込んでいるものをすべて再ビルドし、プロセスを再起動します。
- EOLラインから移行します。Node.js 20、25およびそれ以前にはアップストリームの修正が提供されないため、22か24に移行するか、商用の延長サポートビルドを利用してください。
- 周辺のソフトウェアにもパッチを当てます。Bunは1.4.4に、Envoyはアドバイザリに記載された修正版に、Pythonの
Brotliは1.2.1に更新し、ディストリビューションのbrotliパッケージも更新します。 - ロールアウトが完了するまでの間、公開されている経路では信頼できないBrotliトラフィックを一時的に制限することをImpervaは提案しています。body-parserでは
inflateオプションをfalseに設定できますが、これはgzipを含むすべての圧縮されたリクエストボディを拒否するため、まず実際のクライアントで動作をテストしてください。 - クラッシュを監視します。ImpervaとSysdigはいずれも、Node.jsの予期しない終了やデコーダーのエラーを、攻撃の証拠ではなく調査すべき手がかりとして扱っています。アラートの対象にすべきなのは、クラッシュの直後に同じコンテナ内で新しいプロセスが実行されるパターンです。
よくある質問
Node2Shellは実際に悪用されていますか?
2026年10月24日時点で、Sysdigは実環境での悪用は確認されていないと報告しています。また10月23日時点で、CISAはCVE-2026-111497を既知の悪用された脆弱性(KEV)カタログに追加していません。ただし公開PoCコードが存在し、Impervaは公式Node.jsビルドの1つでコード実行を示しているため、KEVへの掲載を待たずに今すぐパッチを当ててください。
npmの「brotli」パッケージを更新すればCVE-2026-111497は修正されますか?
いいえ。脆弱なデコーダーはNode.jsランタイムにコンパイルされて組み込まれています。この欠陥を取り除けるのは、Node.js 22.23.4、24.22.1、26.12.1以降(Debianの場合はパッチ適用済みのシステムのbrotliパッケージ)だけです。
Node.js 20を使っています。どうすればよいですか?
Node.js 20はサポートが終了しており、CVE-2026-111497に対するアップストリームの修正は提供されません。Node.js 22.23.4または24.22.1にアップグレードしてください。すぐにアップグレードできない場合は、信頼できない入力に対するBrotliのデコードをブロックまたは無効化し、商用の延長サポートビルドも検討してください。
ブラウザは影響を受けますか?
CVEレコードと本記事で引用したアドバイザリが対象としているのは、BrotliのCライブラリと、それを同梱するNode.js、Bun、Envoy、Pythonパッケージなどのプロジェクトです。いずれもブラウザには言及していないため、影響の有無を決めつけず、各ブラウザベンダーのリリースノートを確認してください。
Node2Shellを発見したのは誰ですか?
Node.jsは、研究者のKhai Tran氏とSylvie Mayer氏によるOpenAI Codex Securityをクレジットしています。その後、Impervaがこのバグを「Node2Shell」と名付け、コード実行を実証しました。
出典
- Node.js:2026年10月21日のセキュリティリリース
- CVE-2026-111497のレコード(cve.org)
- Google Brotli v1.2.1リリース
- Imperva:Node2Shell, From Brotli Data to Remote Code Execution
- Envoyアドバイザリ GHSA-3wvj-j6qm-62mr
- Bun v1.4.4リリースノート
- Debianセキュリティトラッカー:CVE-2026-111497
- Sysdig:Detecting the Node.js Brotli RCE
- HeroDevs:CVE-2026-111497(Node2Shell)
- expressjs/body-parser README
- PyPI: Brotli、PyPI: brotlicffi