2026年10月21日から23日(日本時間)にかけて、圧縮したデータをほどく(展開する)部品「Brotli」の脆弱性 CVE-2026-111497 の直しが、Node.js、部品の元の Google、Python の brotli と brotlicffi、Bun から出ました。脆弱性とは、悪用されると困ることが起きうる、ソフトウェアの弱点のことです。GitHub の告知の題では「Node2Shell」と呼ばれています。時刻はすべて日本時間です(告知の UTC の時刻に 9 時間を足しました)。
壊れているのは、データを「展開する側」です。Brotli を中に持つほかの道具も同じように当たる、と Bun の告知は書いています。
先に答えを書きます。ここがいちばん大事なところです。
- 当たるかは、使っている物の版で決まります。 Node.js は 22.23.4・24.22.1・26.12.1 以上、Python の
brotliは 1.2.1 以上(brotlicffiは 1.2.1.0 以上)、Bun は 1.4.4 以上が直った版です。Bun のbun build --compileで作った実行ファイルは、1.4.4 で作り直すまで当たったままです(→「当たる版と、直った版」) - 公式の Node.js は
node --versionで見ます。process.versions.brotliの番号では決めません。 直った公式の Node.js でも、1.1.0・1.2.0 と、直す前と同じ番号が出るためです。Debian の apt で入れた nodejs と Homebrew の node は、OS・Homebrew のbrotliの版も見ます(→「Node.js:node --version で見る」) - Python は
pip show brotliで見ます。入れた覚えが無くても、ほかの部品の依存で入っていることがあります。Required-by:が空でも、使われていないとは限りません。Debian の apt で入れた brotli(python3-brotli)は、直っても古い番号のまま出るので、apt の版で見ます(→「Python:pip show brotli で見る」) - mitmproxy 12.3.0 を使っていると、
brotliを 1.2.1 に上げられない書き方になっています(10月24日時点の依存の記述)(→「mitmproxy・yt-dlp を使っているとき」) - 悪用は、2026年10月24日14時57分ごろまでに見た範囲では、確かめられたという文がありません。 CISA の評価は「悪用の知らせなし(none)」で、KEV にも載っていません。悪用が確かめられていても、いなくても、やることは同じで、上げます(→「悪用はされている?(2026年10月24日時点)」)
初心者がまずやることは、版を見ることです。Node.js なら node --version、Python なら pip show brotli、Bun なら bun --version です。
書いてあることは、CVE の記録・Google・Node.js・Python の部品の置き場(PyPI)・Bun・GitHub・Debian と Ubuntu・公的機関の一覧などを、2026年10月24日の14時45分から15時4分ごろ(日本時間)に開いて確かめたもの(uv と pip の上げ方の文書は15時52分ごろ)です。手元の出力は、同じ日の14時51分から14時55分ごろと、15時54分ごろ(uv で上げる手順)に、公式の Docker のイメージの中で流しました。壊れたデータや攻撃の入力は、流していません。
- 何の脆弱性か(圧縮したデータをほどく部品 Brotli)と、Node2Shell という呼び名。点数は誰が付けたものか
- Node.js・Python の
brotli/brotlicffi・Bun の、当たる版と直った版 - 自分の環境の確かめ方(
node --version・pip show・依存で入ったか)と、番号が古いまま出るときの読み方 - すぐ上げられないときに Bun の告知が挙げる手立てと、上げられない部品があるとき
- 悪用は確認されているか(2026年10月24日時点)
10月に、Brotli で何があった?
Brotli は、データを小さく縮めて送る(圧縮する)ための方式と、その部品です。ウェブの通信などで、縮めて送られてきたデータを、受け取った側が「展開」して元に戻します。今回の脆弱性は、この展開する部品の誤りです。
告知が出た順(日本時間)
| 日時 | 出たもの |
|---|---|
| 10月21日 19時38分 | Node.js 22.23.4・24.22.1・26.12.1 のリリース |
| 10月22日 4時27分 | Google の Brotli 1.2.1・1.1.1・1.0.10 |
| 10月22日 19時11分 | Bun 1.4.4 のリリース |
| 10月22日 22時35分 | CVE の記録(CVE-2026-111497) |
| 10月22日 22時57分 | PyPI の Brotli 1.2.1 |
| 10月23日 0時32分 | GitHub の告知 GHSA-9v8h-qqgm-4m35(題に Node2Shell) |
| 10月23日 1時19分 | PyPI の brotlicffi 1.2.1.0 |
| 10月23日 18時31分 | Bun の告知 GHSA-663w-cv8g-jj2p |
Bun は、告知より前に 1.4.4 を出していました。
告知が書いていること
CVE の記録の説明は、Brotli の展開の部品(c/dec/decode.c)のバッファのあふれ(用意した入れ物をあふれて書き込んでしまう誤り)です。当たるのは 1.0.3 から 1.2.0 まで(細かい範囲は→「当たる版と、直った版」)、すべての環境です。外にいる、認証の無い攻撃者が、細工した Brotli のデータで、隣のメモリを壊す、メモリの中身を漏らす、止める、場合によってはコードを動かす、と書いています。
Node.js の言い方は、こうです。Node.js に入っている Brotli の展開の部品で、壊れた圧縮データが内部の入れ物の端を越えて書き込みます。アプリが node:zlib で展開する Brotli のデータを渡せる攻撃者は、プロセスのメモリを壊せ、落ちる、メモリが漏れる、遠隔でのコードの実行につながりうる、とブログは書いています。
Bun の言い方は、こうです。Bun 自身のコードの誤りではなく、Brotli の部品の誤りで、Brotli を中に持つほかのプロジェクトも同じように当たります。
告知の文は、どれも「展開」の話です。Google の告知は、CVE の記録とリリースの文だけでした。10月24日14時55分ごろまでに探した範囲では、Google のブログなどは見つかりませんでした。
たとえ話で見ると
圧縮して小さくした荷物が、次々に届きます。係の人が荷物をほどいて、中身を作業台に並べます。作業台には、決まった大きさの台があり、ほどいた中身はいったんそこに置かれます。ところが、ほどく係に誤りがあって、中身が台の端を越えて、隣の台にまで置かれてしまうことがあります。隣の台には、別の作業の物が置いてあります。起きうるのは、隣の台の物が壊れる、他人の書類を見られる、店を閉めさせられる、場合により外から機械を好きに動かされる、の 4 つです。
例えの物と、実際の物の対応は、次のとおりです。
- 荷物をほどく係:Brotli の展開の部品
- 決まった大きさの台:部品の内部の入れ物(バッファ)
- 台の端を越えて、隣に置いてしまう:範囲の外への書き込み
- 荷物を送ってくる相手:Brotli のデータを送れる相手(送られてくる本文・取りに行った先の応答)
告知の言い方では、こうなります。Brotli の展開の部品に、範囲の外への書き込みがあり、細工した Brotli のデータで、メモリを壊す、メモリの中身を漏らす、止める、場合によってはコードを動かすことができる、と CVE の記録は書いています。
Node2Shell という呼び名
「Node2Shell」は、GitHub の告知の題にある呼び名です。CVE の記録・Node.js のブログ・Google のリリース・Bun の告知には、この呼び名はありません(10月24日14時57分ごろに、各本文の語を数えました)。セキュリティの会社の Aikido は、10月23日の記事の題で「HTTP2Shell に広がった」と書いていて、HTTP2Shell は Aikido の呼び名です。
点数は、誰が付けたもの?
同じ脆弱性でも、出どころによって、点や重さの言葉が違います。
| どこが | 何と付けたか | 物差し |
|---|---|---|
| 番号を付けた Google(CNA) | 9.2(CRITICAL) | CVSS 4.0 |
| GitHub の告知(GHSA-9v8h) | critical(同じ 9.2) | CVSS 4.0 |
| Node.js のブログ | high(点の数は無い) | ── |
| Bun の告知 | high(点は付いていない) | ── |
| Ubuntu | 優先度 medium | Ubuntu の優先度 |
10月24日14時50分ごろに見た範囲では、NVD(アメリカの脆弱性のデータベース)は自分の点を付けておらず、「分析待ち(Awaiting Analysis)」でした。Google の点が、NVD 自身の点ではない「Secondary」の点として載っています。CVSS 3.1 の点は、見た範囲では見つかりませんでした。点数の読み方は、脆弱性の知らせの読み方の「同じ脆弱性なのに点が違うのはなぜ?」に書きました。
自分は当たる? 版で決める
当たるかは版で決まります。どんな使い方をしているかは、どれくらい急ぐかの目安です。
当たる版と、直った版
| 物 | 当たる版(告知の原文の範囲) | 直った版 |
|---|---|---|
Brotli の部品そのもの(C の部品。Homebrew の brotli など) | 1.0.3 以上 1.0.10 未満・1.1.0 以上 1.1.1 未満・1.2.0 以上 1.2.1 未満 | 1.0.10・1.1.1・1.2.1 |
| Node.js | 26.x・24.x・22.x | 26.12.1・24.22.1・22.23.4 |
Python の brotli | 1.0.3 以上 1.2.1 未満 | 1.2.1 |
Python の brotlicffi | 1.0.3 以上 1.2.1.0 未満 | 1.2.1.0 |
| Bun | 1.0.21 以上 1.4.4 未満 | 1.4.4 |
表の補足です。
- 10月24日14時47分ごろに見た範囲では、PyPI に 1.1.1 と 1.0.10 はありません。pip で入れた人が上げる先は、1.2.1 だけです。
- サポートの終わった Node.js は、いつも当たる、と Node.js のブログは書いています。どの版が終わったかは、10月の脆弱性まとめにあります。
- pip で入れた
brotliが 1.1.0 のままの人は、前の件(CVE-2025-6176)にも当たります。 - 公式の Node.js の中の Brotli は、Node.js の行(Node.js の版)で見ます。Debian の apt の nodejs と Homebrew の node は、OS・Homebrew の
brotliの版で見ます(→「OS のパッケージ(Debian・Ubuntu)で入れたとき」)。上の「Brotli の部品そのもの」の行の番号と、process.versions.brotliを比べません。
外からのデータは、どこから届く?
ここからは、急ぐ度合いの目安です。当たるかどうかは、上の版で決まります。
- Node.js:告知は「
node:zlibで展開する」とだけ書いています。Express 5 の既定の部品 body-parser 2.x は、br(Brotli)で圧縮されて送られてきた本文を、既定で展開する、と body-parser の文書は書いています。これは body-parser の文書の文で、Node.js の告知の文ではありません。body-parser 2.0.0 で Brotli に対応し、express 5.3.0 は body-parser ^2.3.0 に依存します。 - Bun:告知が挙げるのは、
fetch(brの応答を自動でほどきます。つなぐ先の悪いサーバーと、暗号化していない通信の途中にいる攻撃者を含みます)、node:zlib、DecompressionStreamです。 - Python:告知に使い方の文はありません。各 HTTP の道具の文書が、brotli か brotlicffi が入っていれば
brを扱う、と書いています(requests・aiohttp・urllib3。httpx は古い名前の brotlipy のまま書いています)。手元で、requests は brotli を入れると、名乗りがgzip, deflateからgzip, deflate, brに変わりました(試した結果)。
requests と urllib3 の版、名乗り(ブラウザーやライブラリが「この圧縮を受け取れる」とサーバーに伝える欄)の順に出しています。
## brotli なし
2.34.2 2.8.0 gzip, deflate
## brotli あり
2.34.2 2.8.0 gzip, deflate, br
Node.js:node --version で見る
公式の Node.js の直った版は、22.23.4・24.22.1・26.12.1 の 3 つです。版の見方と、公式イメージで流した出力は、10月の脆弱性まとめの Node.js の節にあります。
直った公式の Node.js でも、process.versions.brotli は古い番号のままです。 Node.js は、Brotli の版を上げずに、直しだけを取り込みました。公式の node イメージの中で、2026年10月24日の14時52分ごろに流した結果です。3 つとも直った版です。
(node:22-slim)
$ node --version
v22.23.4
$ node -p process.versions.brotli
1.1.0
(node:24-slim)
$ node --version
v24.22.1
$ node -p process.versions.brotli
1.2.0
(node:26-slim)
$ node --version
v26.12.1
$ node -p process.versions.brotli
1.2.0
そのため、process.versions.brotli の番号では、直ったかどうかを決められません。node --version を、直った版と比べます。
Homebrew の node は、同梱の Brotli を使わず、Homebrew の brotli を使うように作られています(Homebrew の式(作り方の定義)を読んだ範囲。node と node@24 は同梱の Brotli を外し、node@22 は Homebrew の brotli の置き場を渡して作ります)。ですから、Homebrew の node では、上の表の「Brotli の部品そのもの」の行で、Homebrew の brotli が 1.2.1 以上かを見ます。見るコマンドは brew list --versions brotli です(入っていなければ何も出ません。brew info brotli の stable 1.2.1 は、入っている版ではありません)。Homebrew の brotli 1.2.1 と、node・node@24・node@22 の直った版(26.12.1・24.22.1・22.23.4)は、どちらも10月22日の朝に Homebrew に入っています。
Debian の apt で入れた nodejs は、OS の Brotli の部品を使う、と Debian の追跡は書いています。この場合は node --version ではなく、Debian の brotli のパッケージの版を、追跡の fixed の版と比べます(→「OS のパッケージ(Debian・Ubuntu)で入れたとき」)。nodejs のときに部品の版を見るコマンドは、この記事では流していません。python3-brotli は Python の部品の名前です。
npm で見られるもの
Node.js の Brotli は Node.js の中にあり、npm の部品ではありません。そのため npm ls brotli では見えません((empty) と出ました)。npm にも brotli という名前の部品がありますが、WOFF2 用の別の物で、10月24日14時54分ごろに見た範囲では、この件の告知や記録は見つかりませんでした。
npm で見るのは、Brotli のデータがどこから入るかです。node:24-slim(npm 11.19.1)で、空のプロジェクトに npm install express@5 を入れた結果です。
$ npm ls body-parser
app@1.0.0 /app
`-- express@5.3.0
`-- body-parser@2.4.0
$ npm explain body-parser
body-parser@2.4.0
node_modules/body-parser
body-parser@"^2.3.0" from express@5.3.0
node_modules/express
express@"^5.3.0" from the root project
$ npm ls brotli
app@1.0.0 /app
`-- (empty)
$ npm ls bun
app@1.0.0 /app
`-- (empty)
npm ls は入っている部品の版を木の形で出し、npm explain(別名 npm why)は、その部品が入った依存のつながりを出します。npm ls bun が (empty) なのは、このプロジェクトに Bun を入れていないためです。npm で Bun を入れている場合に見る形が npm ls bun で、Bun を入れた状態の出力は流していません。
Python:pip show brotli で見る
ふつうの Python(CPython)では brotli、PyPy などでは brotlicffi が入る書き方が多くあります。CPython の環境で pip show brotlicffi を流すと、WARNING: Package(s) not found: brotlicffi と出ました。
入れた覚えが無くても、ほかの部品の依存で入る
2026年10月24日14時48分ごろに、PyPI に書かれた各道具の依存の記述を読んだものです。各道具の告知ではありません。
| 道具・版 | brotli についての依存の記述(原文のまま) |
|---|---|
| gradio 6.30.0 | brotli>=1.1.0 |
| scrapy 2.19.0 | brotli>=1.2.0(PyPy は brotlicffi>=1.2.0.0) |
| flask-compress 1.25 | brotli(版の指定なし。PyPy は brotlicffi) |
| yt-dlp 2026.10.21 | extra の default で brotli、extra の pin で brotli==1.2.0 |
| mitmproxy 12.3.0 | Brotli<=1.2.0,>=1.0 |
| urllib3 2.8.0・httpx 0.28.1・aiohttp 3.14.5 | extra を指定したときだけ入る |
| requests 2.34.2 | 依存に書かない(入っていれば使う) |
>=1.2.0 の書き方は、1.2.0(当たる版)も入りうる書き方です。どの版が入るかは、入れた日によります。
pip show の読み方:Version と Required-by
flask-compress==1.25 を入れたあと(brotli は依存で入りました)に、python:3.13-slim の中で流した結果です(2026年10月24日14時51分ごろ)。
$ pip show brotli
Name: brotli
Version: 1.2.1
…
Location: /v/lib/python3.13/site-packages
Requires:
Required-by: Flask-Compress
Version: が入っている版です。Required-by: は、それを依存に書いた部品です。この例では Flask-Compress が brotli を必要としています。pip の文書の例には Required-by: の行が無いので、行の意味は手元の出力で見せています。Location: の行は、OS のパッケージを見分けるときに使います(→「OS のパッケージ(Debian・Ubuntu)で入れたとき」)。
Required-by: が空でも、使われていないとは限りません。 extra(httpx[brotli] のように [ ] で足す追加の部品)で入ったときは、空でした(試した結果。pip の文書にこの関係の文はありません)。
(pip で httpx[brotli]==0.28.1 を入れた)
$ pip show brotli
Name: brotli
Version: 1.2.1
…
Requires:
Required-by:
requests も brotli を依存に書かないので、Required-by: は空でした。uv の uv tree --invert --package brotli は、(extra: brotli) まで出しました。
$ uv tree --invert --package brotli
Resolved 12 packages in 0.40ms
brotli v1.2.1
└── httpx v0.28.1 (extra: brotli)
└── demo[brotli] v0.1.0
上げる:pip install -U brotli
pip の文書は、-U(--upgrade)を「指定した部品を、いちばん新しい版に上げる」と説明しています。使っている仮想環境(Python の部品を環境ごとに分ける仕組み)の中で流します。1.2.0 の環境で流した結果です。
$ pip show brotli
Name: brotli
Version: 1.2.0
…
$ pip install -U brotli
Requirement already satisfied: brotli in ./v/lib/python3.13/site-packages (1.2.0)
Collecting brotli
Using cached brotli-1.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.metadata (6.1 kB)
…
Installing collected packages: brotli
Attempting uninstall: brotli
Found existing installation: brotli 1.2.0
Uninstalling brotli-1.2.0:
Successfully uninstalled brotli-1.2.0
Successfully installed brotli-1.2.1
$ pip show brotli
Name: brotli
Version: 1.2.1
…
上げたあとは、必ず pip show brotli で版を見ます。uv で作ったプロジェクトは、次の節に進みます(→「uv で作ったプロジェクト」)。
uv で作ったプロジェクト
見る:uv pip show brotli と uv tree --invert --package brotli を使います。uv の文書は、--invert を「その部品に依存する部品を見せる」と説明しています。flask-compress を入れたプロジェクトでの結果です(uv 0.13.5)。
$ uv pip show brotli
Name: brotli
Version: 1.2.1
Location: /p/.venv/lib/python3.13/site-packages
Requires:
Required-by: flask-compress
$ uv tree --invert --package brotli
Resolved 14 packages in 0.30ms
brotli v1.2.1
└── flask-compress v1.25
└── demo v0.1.0
別の仮想環境を有効にしたままだと、uv pip show はそちらの環境を見ました(試した結果。uv の文書の言い方は開いていません)。どの環境を見ているかは、Location: の行で確かめます。
上げる:次の順で考えます。
- brotli だけを上げるのは、
uv lock --upgrade-package brotliです。ほかの部品はロックの版のままです。uv はロックした版を優先し、新しい版が出てもロックを古いと見なさない、と uv の文書は書いています。 uv lockが変えるのは、ロックファイルだけです。入っている物はuv syncで変わります。下の出力は、下限だけの書き方(brotli>=1.2.0)のプロジェクトです。- 同じ旗は
uv sync・uv runにも付けられ、ロックと入っている物の両方を変えます。extra のhttpx[brotli]で入った brotli も、uv sync --upgrade-package brotliの 1 回で 1.2.1 になりました(依存の書き方が許す範囲でです。→ 4)。 - 上げられるのは、依存の書き方の範囲までです。 自分で
brotli==1.2.0と固定していると、uv lock --upgrade-package brotliは何も言わずに 1.2.0 のままでした(終了コード 0)。そのときはuv add 'brotli>=1.2.1'で書き方を変えます。今の行と、足す行の条件(markers。; platform_python_implementation != "PyPy"のような物)が違うと、書き換えずに別の行を足す、と uv の文書は書いています。 - 依存の側に上限があって止まるのも、同じ止まり方です(→「mitmproxy・yt-dlp を使っているとき」)。
- 上げたあとは、必ず版を確かめます。
uv tree --invert --package brotliかuv pip show brotliで、1.2.1 になったかを見ます。黙って上がらないことがあるためです。上げる前と後で、変わったのは brotli の 1 行だけでした(uv exportの出力を比べた結果)。
uv の使い方は、uv の使い方にまとめてあります。
(下限だけの書き方。上げる前のロックは 1.2.0)
$ uv lock --upgrade-package brotli
Resolved 2 packages in 559ms
Updated brotli v1.2.0 -> v1.2.1
$ uv pip show brotli
Name: brotli
Version: 1.2.0
…
$ uv sync
Resolved 2 packages in 0.75ms
Uninstalled 1 package in 0.43ms
Installed 1 package in 2ms
- brotli==1.2.0
+ brotli==1.2.1
(自分で 'brotli==1.2.0' と固定した)
$ uv lock --upgrade-package brotli
Resolved 2 packages in 560ms
$ uv tree --invert --package brotli
Resolved 2 packages in 0.47ms
brotli v1.2.0
└── demo-a v0.1.0
$ uv add 'brotli>=1.2.1'
…
- brotli==1.2.0
+ brotli==1.2.1
…
$ uv pip show brotli
Name: brotli
Version: 1.2.1
…
(extra の httpx[brotli] で入った。上げる前のロックは 1.2.0)
$ uv tree --invert --package brotli
…
brotli v1.2.0
└── httpx v0.28.1 (extra: brotli)
└── demo-c[brotli] v0.1.0
$ uv sync --upgrade-package brotli
…
- brotli==1.2.0
+ brotli==1.2.1
$ uv tree --invert --package brotli
…
brotli v1.2.1
└── httpx v0.28.1 (extra: brotli)
└── demo-c[brotli] v0.1.0
mitmproxy・yt-dlp を使っているとき
10月24日時点の mitmproxy 12.3.0 の依存の記述は Brotli<=1.2.0,>=1.0 で、1.2.1 に上げられない書き方です。12.3.0 は10月22日11時28分に出ていて、Brotli 1.2.1 より前の版です。
pip は 1.2.1 に上げますが、衝突を ERROR の行で出し、pip check も衝突を出します(終了コード 1)。
$ pip install -U brotli
…
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
mitmproxy 12.3.0 requires Brotli<=1.2.0,>=1.0, but you have brotli 1.2.1 which is incompatible.
Successfully installed brotli-1.2.1
$ pip check
mitmproxy 12.3.0 has requirement Brotli<=1.2.0,>=1.0, but you have brotli 1.2.1.
uv は、uv lock --upgrade-package brotli でも 1.2.0 のままでした(黙って止まります。終了コード 0)。uv add 'brotli>=1.2.1' は、解けずに止まりました。
$ uv lock --upgrade-package brotli
Resolved 46 packages in 569ms
$ uv tree --invert --package brotli
…
brotli v1.2.0
└── mitmproxy v12.3.0
└── demo2 v0.1.0
この記事では、mitmproxy を使ったまま brotli を 1.2.1 にして動かす道は確かめていません。PyPI の mitmproxy のページで、依存の記述が変わったかを開き直します。
yt-dlp は、10月24日時点の 2026.10.21 の依存の記述が、extra の pin で brotli==1.2.0(当たる版に固定)です。extra の default は、版を指定しない brotli です。どちらの extra を選ぶかの判断は、この記事では書きません。
OS のパッケージ(Debian・Ubuntu)で入れたとき
2026年10月24日14時50分ごろに見た範囲では、次のとおりです。
| OS | brotli の状況 |
|---|---|
| Debian 12(bookworm) | 1.0.9-2+deb12u1(DLA-4855-1)で直った |
| Debian 13(trixie) | 1.1.0-2+deb13u1(DSA-6582-1)で直った |
| Debian forky・sid | 1.2.0-4 のまま(直しは未) |
| Ubuntu | 追跡のどの版も needs-triage(評価待ち。10月23日12時19分の更新)。優先度は medium |
DSA と DLA の本文は開けず、追跡のページだけを見ました。
手元の Debian で、直ったパッケージなのに、pip3 show brotli は 1.1.0・1.0.9 と出ました。 Debian は、本家の番号のまま直しを取り込むためです。apt で入れた物は、Location: /usr/lib/python3/dist-packages と出ました。その場合は、apt-cache policy python3-brotli の版を、Debian の追跡の fixed の版と比べます(trixie の出力です)。
$ pip3 show brotli
Name: Brotli
Version: 1.1.0
…
Location: /usr/lib/python3/dist-packages
Requires:
Required-by:
$ apt-cache policy python3-brotli
python3-brotli:
Installed: 1.1.0-2+deb13u1
Candidate: 1.1.0-2+deb13u1
…
Debian の追跡は、Debian の nodejs は OS の Brotli の部品を使う、と書いています。Debian の apt で入れた nodejs も、この表の版(追跡の fixed の版)と比べます。nodejs のときに部品の版を見るコマンドは、この記事では流していません。python3-brotli は Python の部品の名前です。
Bun は当たる? 1.4.4 と、作った実行ファイル
Bun の告知(GHSA-663w-cv8g-jj2p)が書く当たる版は、1.0.21 以上 1.4.4 未満で、直った版は 1.4.4 です。1.4.3 は Brotli 1.2.0 を持ち、1.4.4 で Brotli 1.2.1 に上げました。
bun build --compile で作った実行ファイルは、Bun の本体を中に持っています。そのため、1.4.4 で作り直すまで、当たったままです。上げ方は、告知が「1.4.4 に上げ、bun build --compile で作った実行ファイルを 1.4.4 で作り直す」と書いています。
Bun は、Bun で攻撃を試していません。影響が他のソフトと同じかは分からないので、遠隔のコード実行の危険として扱ってください、と告知は書いています。
版の見方(bun --version)と上げ方は、同じ 1.4.4 が出てくるHTTPS の証明書の鍵が漏れた件の記事にまとめました。npm で入れた Bun は、npm ls bun で見ます。
10月24日14時50分から55分ごろに見た範囲では、この告知は GitHub の全体の一覧(GitHub Advisory Database)にありませんでした。そのため、Bun の告知のページで確かめます。
すぐ上げられないとき(Bun の告知)
Bun の告知は、次のように書いています。プロセス全体の手立ては、ありません。
fetchにdecompress: falseを渡すと、その要求だけ、brを名乗らず、応答をほどきません- 信用できないデータを、
node:zlibの Brotli の関数や、DecompressionStreamのbrotliに渡さない
これらはつなぎです。上げるのが先です。
悪用はされている?(2026年10月24日時点)
2026年10月24日14時46分から14時57分ごろ(日本時間)に見た範囲では、悪用が確かめられた、という文は見つかりませんでした。
| 出どころ | 確かめたこと |
|---|---|
| CISA が CVE の記録に付けた評価(SSVC) | Exploitation(悪用)は none(知らせなし)。10月24日12時55分の更新です |
| CISA の KEV(悪用が確認された脆弱性の一覧) | 版 2026.10.23(10月24日4時30分に出た版、1756件)に、CVE-2026-111497 はありません |
| JPCERT/CC の注意喚起の一覧(2026年) | 最終更新は10月23日で、Brotli・Node.js の項目はありません |
| IPA の重要なセキュリティ情報(2026年) | Brotli・Node.js の項目はありません |
| JVN | トップ(最終更新 10月23日)に Brotli・Node.js はありません。JVN iPedia と MyJVN は10月22日から止まっていて、検索できませんでした |
| 当事者の告知 | Node.js のブログ・CVE の記録の説明・GitHub の告知・Bun の告知の本文に、悪用の文はありません |
KEV に無いことは、悪用されていない証明ではありません。この考え方は、脆弱性の知らせの読み方にあります。上に書いたのは、この時刻までに見つかった範囲です。
悪用が確かめられていても、いなくても、やることは同じです。直った版に上げます(→「当たる版と、直った版」)。
よくある質問
process.versions.brotli が 1.2.0 と出ます。当たっていますか?
この番号では決まりません。直った Node.js 24.22.1・26.12.1 でも 1.2.0、22.23.4 は 1.1.0 と出ます。node --version を、直った版(22.23.4・24.22.1・26.12.1)と比べます(→「Node.js:node --version で見る」)。
圧縮する(データを縮める)だけなら、当たりませんか?
告知の文は、どれも展開する側の話です。ただし、10月24日に開いた範囲では、「圧縮するだけなら安全」と書いた告知は、見つかりませんでした。直った版に上げます。
requests を使っています。当たりますか?
requests は brotli を依存に書いていませんが、入っていれば br の応答を自動でほどく、と requests の文書は書いています。当たるかは brotli の版で決まるので、pip show brotli を見ます(→「pip show の読み方:Version と Required-by」)。
npm ls brotli で何も出ません。安全ですか?
Node.js の Brotli は Node.js の中にあり、npm の部品ではないので、npm ls には出ません。安全かどうかの印ではありません。node --version で見ます(→「Node.js:node --version で見る」)。
Debian で pip show brotli が 1.1.0 と出ます。当たっていますか?
OS のパッケージは、番号が古いまま直ります。apt-cache policy python3-brotli の版を、Debian の追跡の fixed の版と比べます(→「OS のパッケージ(Debian・Ubuntu)で入れたとき」)。
- Node.js を
node --versionで見て、自分の系統の直った版(22.23.4・24.22.1・26.12.1)以上か。process.versions.brotliの番号で決めていないか。Debian の apt で入れた nodejs は OS の、Homebrew の node は Homebrew のbrotliの版で見る(brew list --versions brotli。→「OS のパッケージ(Debian・Ubuntu)で入れたとき」)(→「Node.js:node --version で見る」) - Python の環境ごとに
pip show brotli(PyPy はbrotlicffi)を見て、1.2.1 以上(1.2.1.0 以上)か。Required-by:が空でも上げたか(→「pip show の読み方:Version と Required-by」) - mitmproxy・yt-dlp の依存の記述で、1.2.0 に固定されていないか(→「mitmproxy・yt-dlp を使っているとき」)
- OS のパッケージの brotli は、apt の版を追跡の版と比べたか(→「OS のパッケージ(Debian・Ubuntu)で入れたとき」)
- Bun は 1.4.4 以上か。
bun build --compileで作った実行ファイルを作り直したか(→「Bun は当たる? 1.4.4 と、作った実行ファイル」) - uv のプロジェクトは、上げたあと
uv tree --invert --package brotliで 1.2.1 になったかを見たか(→「uv で作ったプロジェクト」) - 悪用の状況を、上の時刻より後に開き直したか(→「悪用はされている?(2026年10月24日時点)」)
まとめ
- CVE-2026-111497 は、圧縮したデータをほどく部品 Brotli の脆弱性です。GitHub の告知の題では Node2Shell と呼ばれています。点は、Google(CNA)が CVSS 4.0 で付けた 9.2 です
- 当たるかは、使っている物の版で決まります。Node.js は 22.23.4・24.22.1・26.12.1、Python の
brotliは 1.2.1、brotlicffiは 1.2.1.0、Bun は 1.4.4 以上が直った版です - 公式の Node.js は
node --versionで見ます。直った版でもprocess.versions.brotliは古い番号のままなので、その番号では決めません - Python は
pip show brotliで見ます。ほかの部品の依存で入ることがあり、Required-by:が空でも使われていないとは限りません。Debian の apt で入れた物は、apt の版で見ます - uv のプロジェクトは
uv lock --upgrade-package brotliとuv syncで上げ、上げたあとに版を確かめます。固定や依存の側の上限があると、黙って上がらないことがあります - Bun の
bun build --compileで作った実行ファイルは、1.4.4 で作り直すまで当たったままです - 悪用は、10月24日14時57分ごろまでに見た範囲では、確かめられた文が見つかりませんでした。KEV に無いことは、悪用されていない証明ではありません。やることは同じで、上げます
- この記事で確かめていないこと:Windows・Mac での
pip show・uv の出力、Homebrew と Mac の公式インストーラの node のprocess.versions.brotli、PyPy の brotlicffi、pip-audit と npm audit の出力、yt-dlp の公式の実行ファイルの中の版、mitmproxy を brotli 1.2.1 で動かしたとき、Red Hat・Alpine など Debian・Ubuntu 以外の OS、ブラウザーやほかの製品、uv のほかの上げ方や、ほかの道具での上げ方
Node.js の 10月の 10 件の全体は、10月の脆弱性まとめに書きました。
参考資料
この記事の内容は、2026年10月24日(日本時間の14時45分から15時4分ごろ。uv と pip の上げ方の文書は15時52分ごろ)に開いた文書をもとにしています。悪用の状況と各 OS の直しは、日ごとに変わります。
- 番号・告知: CVE の記録・NVD・GitHub の告知 GHSA-9v8h-qqgm-4m35・Google Brotli 1.2.1 のリリース・Google Brotli の CHANGELOG
- Node.js: 10月のセキュリティリリース・process の文書
- Python: PyPI の Brotli・PyPI の brotlicffi・brotlicffi の HISTORY・requests の文書
- Bun: Bun の告知 GHSA-663w-cv8g-jj2p・Bun の文書(インストール)
- Express: body-parser の README
- 確かめ方・上げ方: pip show・pip install・uv tree・uv: ロックした版の上げ方・uv: 依存の変え方・npm ls・npm explain
- OS: Debian の追跡・Ubuntu
- 公的機関: CISA: KEV の一覧のページ・JPCERT/CC: 注意喚起の一覧(2026年)・IPA: 重要なセキュリティ情報(2026年)・JVN
- 呼び名の出どころ: Aikido の記事(10月23日)
※この記事は、2026年10月24日時点の公式の資料と照らして確かめています。誤りに気づいたらお問い合わせからお知らせください。



