1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Node.jsの脆弱性 Node2Shell の確認と更新手順 Homebrew・Docker・Python別

1
Last updated at Posted at 2026-10-24

2026年10月24日 日本時間22時時点の情報です。最新の状況は末尾の出典で確認してください。

3行まとめ

Node.js などの不具合を突かれ、外の誰かにプログラムを動かされるおそれ。Node.js の修正版は 22.23.4/24.22.1/26.12.1。最初に確かめるのは、node --version が修正版以上かと、Homebrew で入れたなら brotli も 1.2.1 かの2つ。

  • Node.js などに入っている圧縮データの展開処理「Brotli」に、外から好きなプログラムを動かされるおそれのある不具合が見つかりました。番号は CVE-2026-111497 で、X では Node2Shell、HTTP2Shell と呼ばれています。
  • 修正版は Node.js 22.23.4/24.22.1/26.12.1、Bun 1.4.4、Python の Brotli 1.2.1/brotlicffi 1.2.1.0 です。Homebrew で入れた Node.js は、brotli も 1.2.1 に更新します。
  • Content-Encoding: br のリクエストを止める回避策では、自分から取りに行った応答は守れません。更新までの時間稼ぎにしてください。

一言でいうと何の話か

圧縮データを元に戻す処理 Brotli に不具合があり、壊れたデータを渡されると外の誰かにプログラムを動かされるおそれがある。対象は Node.js・Bun・Python の Brotli/brotlicffi・Envoy で、それぞれに修正版がある。中で Envoy を使う Istio は、10月24日時点で告知と修正版を確認できず。

Google の圧縮プログラム Brotli の展開処理に、壊れたデータを渡すとメモリを書き換えてしまう不具合がありました。悪用されると、外の誰かに自分のサーバーやパソコンでプログラムを動かされるおそれがあります。Brotli は多くのソフトに組み込まれているので、Node.js だけでなく、Bun(JavaScript/TypeScript のアプリを作って動かす道具一式)、Python のパッケージ、Envoy(通信を中継するソフト)にもそれぞれ修正版が出ています。(OSV、Node.js 公式)

対象 影響を受ける版 修正版
Node.js 22.x/24.x/26.x の修正版より前。25.x/23.x/20.x 以前は修正版なし 22.23.4/24.22.1/26.12.1
Bun 1.0.21 以上 1.4.4 未満 1.4.4
Python の Brotli 1.2.0 以下 1.2.1
Python の brotlicffi 1.2.0.x 1.2.1.0
Envoy 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
Brotli 本体 1.0.3〜1.2.0 1.0.10/1.1.1/1.2.1

(Node.js 公式、Aikido、Bun、PyPA の記録、Aikido の Python 解説、Envoy、OSV)

Istio は通信の中継に Envoy を使っています。10月24日時点では、Istio のセキュリティ情報にこの件の告知は見当たらず、修正版は確認できませんでした。(Istio のアーキテクチャ、Istio のセキュリティ情報)

読む人ごとにやること

読む人ごとに持ち帰ること。企業は使っている物を洗い出す、非エンジニアは担当者に3つ聞く、エンジニアは更新後に番号を確かめる。

今回の件で、読む人ごとに確認してほしいことです。

Web サービスを持つ企業の方

  1. 自社のサービスが、Node.js・Bun・Python・Envoy・Istio のどれを使っているかを洗い出します。
  2. 修正版への更新の日程を決めます。一時しのぎの対策は一部の通信しか守れないので(詳しくは「すぐ更新できないとき」)、日程を決めるところまでが対応です。

非エンジニアの方

自分でサーバーを触らない立場なら、Web サービスの開発会社や社内の担当者に次の3点を聞くと話が早いです。

  1. うちのサービスは Node.js・Bun・Python・Envoy・Istio のどれかを使っていますか?
  2. CVE-2026-111497(今回の脆弱性の番号。Node2Shell とも呼ばれる)の修正版にはもう更新しましたか?
  3. まだなら、いつ誰が更新しますか? それまでの一時しのぎの対策は入れますか?

エンジニアの方

  1. node --version が 22.23.4/24.22.1/26.12.1 以上かを確かめます。
  2. Homebrew で入れているなら、brew list --versions node brotli で brotli が 1.2.1 以上かも確かめます。node --version が新しくても、brotli が古いままだと直っていません。
  3. 本番のサーバーだけでなく、手元のパソコン、bun build --compile で配った実行ファイル、古いタグのまま固定した Docker イメージも作り直します。

入れ方ごとの更新手順を、次の節で紹介します。

入れ方ごとの更新手順

入れ方ごとの確かめるコマンドと更新するコマンド。Homebrew、nvm、Volta、Docker、Bun、Python(pip)。

どの入れ方でも、確かめる → 更新する → もう一度確かめる、の順です。修正版の番号は「一言でいうと何の話か」の表を見てください。

まず今のバージョンを見る

node --version

v22.23.4、v24.22.1、v26.12.1 以上なら Node.js 本体は対応済みです。Homebrew で入れた場合は、このあと brotli も確かめます。

Homebrew

Homebrew の node は同梱の Brotli を取り除き、Homebrew の brotli を使う。node --version が新しくても brotli が古いと直らないので、両方を更新する。

Homebrew の node は、Node.js に同梱されている Brotli を取り除いて、Homebrew の brotli を使うようにビルドされています。node@24 と node@22 も同じく Homebrew の brotli を使います。そのため、node と brotli の両方を新しくする必要があります。(Homebrew の node.rb、node@24.rb、node@22.rb)

brew update
brew upgrade node brotli
brew list --versions node brotli

node@24 や node@22 で入れている場合は、node の部分をそれに置き換えます。10月24日時点の Homebrew の最新は、node が 26.12.1、node@24 が 24.22.1、node@22 が 22.23.4、brotli が 1.2.1 です。(Homebrew の node、Homebrew の brotli、Homebrew のマニュアル)

nvm

使っている系統の修正版を入れて、既定のバージョンにします。例は 24 系です。

nvm install 24.22.1
nvm alias default 24.22.1
nvm ls

古いバージョンで入れていたグローバルのパッケージを引き継ぐときは、--reinstall-packages-from を付けます。(nvm の README)

Volta

volta install node@24.22.1

volta install は、指定したバージョンを既定のバージョンにします。手元にまだなければ取得もします。(Volta)

Docker

Dockerfile の FROM を修正版のタグに書き換えて、イメージを作り直します。

FROM node:24.22.1-slim

公式の node イメージには、26.12.1、24.22.1、22.23.4 と、それぞれの -alpine・-slim などのタグが出ています。作り直したイメージの中で node --version を実行して、番号を確かめてください。(Docker Hub の node)

Bun

bun upgrade
bun --version

1.4.4 以上なら対応済みです。bun build --compile で作った実行ファイルは、修正版の Bun で作り直すまで影響が残ります。(Bun のインストール手順、Bun)

Python(pip)

入っているかどうかと、そのバージョンを見ます。

python -m pip show brotli brotlicffi

入っているものだけを更新します。

python -m pip install --upgrade brotli
python -m pip install --upgrade brotlicffi

(pip show、pip install)

Envoy と Istio

Envoy は、Brotli の展開機能(Brotli decompressor)を設定している場合が対象です。表の修正版に更新します。Istio を使っている場合は、Istio のセキュリティ情報で告知を確認してください。(Envoy)

仕組みの前に知っておく言葉

先に知っておく5つの言葉。Brotli、展開、Content-Encoding: br、CVE と CVSS、RCE の説明。

Brotli(ブロトリ)は、Google が作った圧縮の方式とそのプログラムです。Web の通信量を小さくするために、サーバーと、それを利用する側(クライアント)の間で使われています。(Homebrew の brotli、Aikido)

展開は、圧縮されたデータを元に戻すことです。今回の不具合は、この展開の処理にあります。

Content-Encoding: br は、通信が Brotli で圧縮されていることを伝える目印です。br が Brotli のことです。(MDN の Content-Encoding)

CVE は、見つかった脆弱性(悪用できる弱点)に振られる共通の番号です。CVSS は、脆弱性の深刻さを表す点数です。今回は 9.2 で、区分は Critical(緊急)です。(OSV)

RCE(リモートコード実行)は、外部の第三者に、自分のサーバーやパソコンの上で好きなプログラムを動かされることです。

何が起きるのか

壊れた Brotli データを「続きが足りない」と判定し、8バイトの作業用の領域に書き足し続けて、あふれた分が隣のメモリを上書きする。結果はプログラムの停止、メモリの中身の漏えい、RCE。

展開の処理が、壊れたデータを「形式がおかしい」とは判定せず、「続きのデータがまだ足りない」と判定してしまう作りになっていました。そのため、8バイトしかない作業用の領域に、届いたデータを書き足し続けます。領域からあふれたデータは、隣のメモリを上書きします。(Node.js 公式)

Node.js 公式によると、起きうる結果は次の3つです。

  • プログラム(プロセス)が止まる
  • メモリの中身が漏れる
  • 外から好きなプログラムを動かされる(RCE)

原因は Node.js 固有のものではなく、Google の Brotli 本体(C言語のライブラリ)にあります。(PyPA の記録)

どういう条件で狙われるか

入口は、外から届くリクエストと、自分から取りに行った応答の2方向。どちらも Brotli の展開に行き着く。

条件は「攻撃者が用意した Brotli データを、こちらのプログラムが展開すること」です。Node.js 公式は、node:zlib(Node.js に標準で入っている圧縮・展開の機能)で展開する場合を挙げています。

セキュリティ企業 Aikido の解説では、具体的な入口として次の3つが挙げられています。これは Node.js 公式ではなく、Aikido の説明です。(Aikido)

  • Express 5 と body-parser 2.x は、Content-Encoding: br 付きで送られたリクエストの本文を展開する。誰でもそういうリクエストを送れる。
  • fetch() は、Brotli で圧縮された応答を自動で展開する。
  • node:zlib の Brotli 用の関数に、信頼できないデータを渡している。

入口は「外から受け取るリクエスト」と「自分から取りに行った応答」の2方向あります。Bun の fetch も、既定で Brotli の応答を自動展開します。Python でも、Brotli のパッケージが入っていると、urllib3(requests)、httpx、aiohttp が Brotli の応答を自動で展開します。(Bun、PyPA の記録)

実際の攻撃は

Aikido によると、10月22日時点で実際の攻撃は報告されていません。公開された攻撃コードは、わざと守りを弱めた試験用のビルドでしかプログラム実行に成功していません。一方で、研究者が改造していない公式の Node.js 24.22.0 イメージ(Linux arm64)でもプログラム実行に成功したと報告しています。毎回は成功しなかったそうです。(Aikido)

すぐ更新できないとき

br のリクエストを止めると、外から届くリクエストは防げるが、自分から取りに行った応答は防げない。回避策は時間稼ぎで、修正版への更新が必要。

一時しのぎの方法はありますが、どれも穴があります。Node.js 公式は回避策を示していません。(Aikido)

  • 手前のプロキシやロードバランサー、ミドルウェアで、Content-Encoding: br 付きのリクエストを受け付けないようにする。ただしこれで守れるのは外から届くリクエストだけで、自分のプログラムが他のサーバーから取ってきた Brotli の応答は守れません。(Aikido)
  • Bun では、fetch ごとに decompress: false を指定し、信頼できないデータを Brotli の展開に渡さない。Bun は「影響のある版で、プロセス全体に効く回避策はない」としています。(Bun)
  • Python で Brotli のパッケージを外す。この場合、Brotli を送ってくるサーバーがあると、応答が読めなくなったりエラーになったりします。他のプログラムや製品に組み込まれた Brotli の展開処理は残ります。Accept-Encoding(受け取れる圧縮方式の申告)を変えるだけでは不十分です。(Aikido の Python 解説)

Node.js 公式は、サポートが終わった版は「セキュリティリリースのたびに必ず影響を受ける」としています。25.x/23.x/20.x 以前を使っている場合は、回避策でしのぐより、修正版のある 22/24/26 系への移行を進めてください。(Node.js 公式)

自分は対象かのチェックリスト

自分は対象かのチェックリスト。Node.js、Bun、Python、Envoy/Istio のどれかに当てはまれば修正版に更新する。

当てはまるものがあれば、「入れ方ごとの更新手順」で更新してください。

  • Node.js 22.x/24.x/26.x を使っていて、22.23.4/24.22.1/26.12.1 より古い
  • Node.js 25.x/23.x/20.x 以前を使っている(サポート終了版で、修正版は出ない)
  • Homebrew で Node.js を入れていて、brotli が 1.2.1 より古い
  • Bun 1.0.21 以上 1.4.4 未満を使っている、または古い Bun の bun build --compile で作った実行ファイルを配っている
  • Python で Brotli 1.2.0 以下、または brotlicffi 1.2.0.x が入っている
  • Envoy で Brotli の展開機能を設定している、または Istio を使っている

よくある混同

HTTP2Shell は新しい脆弱性ではない

HTTP2Shell は、同じ CVE-2026-111497 の別の呼び名です。Aikido は X で、Node.js と Python に影響する Node2Shell として知られていた CVE-2026-111497 が「HTTP2Shell」になった、と投稿しています。同じ投稿で、HTTP を使う多くのライブラリやアプリが影響を受けると書いています。名前が変わった理由は書かれていません。新しい脆弱性が増えたわけではありません。(Aikido の X 投稿)

深刻度は「Critical 9.2」と「High」の2つがある

CVE の記録(OSV)では、CVSS v4 で 9.2、Critical です。Envoy も同じ 9.2 Critical としています。一方、Node.js 公式の評価は High です。同じ脆弱性への評価なので、どちらを見ても、やることは修正版への更新です。(OSV、Envoy、Node.js 公式)

Homebrew の ca-certificates の更新は別件

同じ時期に、X で Homebrew の ca-certificates(信頼する証明書の一覧)を更新する方法が投稿されていました。こちらは eMudhra という認証局(証明書を発行する組織)の中間証明書8つの秘密鍵が漏れた件で、Brotli とは関係ありません。この件のまとめページは、修正版として Homebrew の ca-certificates を挙げています。(Cloudflare のブログ、eMudhra の件のまとめ、X の投稿)

ややこしいのは、10月21日の Node.js のセキュリティリリース(22.23.4/24.22.1/26.12.1)に、Brotli の修正と eMudhra への対策が両方入っていることです。Node.js をこの版に上げれば、Node.js 側ではどちらも直ります。(Node.js 公式、Node.js の CHANGELOG)

まとめ

今回の不具合は Brotli 本体にあるので、Node.js に限らず、Brotli を中に持つソフトがそれぞれ直しています。回避策は片方の入口しか守れないので、結局は更新が必要です。

まずは node --version を打ってみてください。Homebrew で入れているなら、brew list --versions node brotli で brotli の番号も確かめます。


直したら終わり、じゃないんですよね。

保守先に「こういうことがあって、こう対処して、安全を確認しました」と伝えるところまでやって、やっと一区切り。

いちばんバタバタするのは、たぶんここからです……。

出典

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?