pip-audit のようなPython向けの依存スキャナを回していても、今回の Python/PyPIのBrotli脆弱性(CVE-2026-111497)は、ある時期まで「クリーン」をすり抜けていました。Node.js で node2shell と呼ばれたBrotli デコーダの境界外書き込みは、実は PyPI の brotli・brotlicffi にも及びます。ところが CVE が上流リポジトリ(google/brotli)の名義で登録され、PyPI のパッケージ名に紐付いていなかったため、スキャナが照合できなかったのです。依存する部品の問題が広がる構図はサプライチェーン攻撃とは|手口・防御ツール比較・npm 12の新機構まで実践解説にまとめています。この記事は、なぜ Python 側も影響するのか・なぜスキャナが取りこぼしたのか・どう確実に確認するかを、一次情報と実機で整理します。

PYPI SIDE何が起きたか

同じ Brotli バグが PyPI の brotli・brotlicffi にも及んでいた

  1. 10/21

    上流 Brotli の境界外書き込みが修正

    google/brotli の OOB 書き込み。Node 側が node2shell として注目を集めた

  2. 実は

    PyPI の brotli・brotlicffi も C 束縛

    どちらも上流 Brotli の C コードを同梱。npm の純 JS 版と違い影響する

  3. 紐付け前

    CVE は上流リポ名義で、PyPI 名に未マッピング

    スキャナは brotli==1.2.0 が入っていても何も出さなかった

  4. 10/22

    GHSA-9v8h-qqgm-4m35 が PyPI 名に紐付け

    critical(CVSS v4 9.2)。brotli < 1.2.1・brotlicffi < 1.2.1.0

  5. 10/25

    pip-audit が検知するようになった

    PYSEC-2026-4322+GHSA で 1.2.0 を指摘(当サイト実測)

出典: GHSA-9v8h-qqgm-4m35(2026-10-22 公開・2026-10-23 reviewed・確認 2026-10-25)、Node.js 告知、PyPI の brotli/brotlicffi

30秒でわかる

  • ・何が:node2shell(CVE-2026-111497)の同じ Brotli バグが PyPI の brotli・brotlicffi にも。GHSA-9v8h-qqgm-4m35 は critical
  • ・盲点:CVE が上流リポ名義で、PyPI 名に紐付くまで pip-audit・Dependabot・Safety は照合できなかった
  • ・確認:pip show で版を直に見る。brotli 1.2.1 以上・brotlicffi 1.2.1.0 以上か。スキャナは DB を最新にして回す
  • ・実測:紐付け後(10/25)の pip-audit は 1.2.0 を検知。修正版 1.2.1 はクリーン(当サイト実機)

まずやること

・pip show brotli brotlicffi で版を確認する(brotli 1.2.1 以上・brotlicffi 1.2.1.0 以上なら対応済み)
・pip-audit を使うなら、勧告 DB を最新にしてから回す(紐付け前の「クリーン」は当てにしない)
・CI・本番・コンテナの各環境と、lock ファイルの固定版も同じ目で見る

Python/PyPIのBrotli脆弱性で何が起きたか

まず事実の中心を押さえます。中身のバグは、Node.js の node2shell や HTTP2Shell で語られたものと同一です。上流の Brotli ライブラリ(google/brotli)のデコーダに境界外書き込み(out-of-bounds write)があり、細工した Brotli データを復号させるとバッファの外に書き込み、条件によってはメモリ開示からコード実行に至りうる、と報告されています。影響する上流 Brotli は 1.0.3〜1.2.0 で、修正版は 1.0.10 / 1.1.1 / 1.2.1 です。Node.js を主役にした捉え方はNode2shell(Node.js同梱Brotliデコーダの境界外書き込みRCE)に、上流 Brotli を同梱・利用する HTTP スタック全般への広がりはHTTP2Shell とは|node2shellの正体は上流Brotliの問題にまとめています。

新しく分かったのは、その影響が Python/PyPI にも及ぶことです。GitHub の勧告 GHSA-9v8h-qqgm-4m35(2026-10-22 公開・critical・CVSS v4 9.2)が、PyPI の brotli(1.0.3 以上 1.2.1 未満)と brotlicffi(1.0.3 以上 1.2.1.0 未満)を影響対象として明記しました。理由はシンプルで、どちらのパッケージも上流 google/brotli の C コードを内部に同梱する束縛だからです。brotli は Google 自身が公開する「Brotli 圧縮ライブラリの Python 束縛」、brotlicffi は同じ C ライブラリへの CFFI 束縛で、いずれも native な Brotli デコーダを抱えています。

どこ Brotli の持ち方 影響・修正版
上流 google/brotli 本体(部品そのもの) 1.0.3〜1.2.0 が影響 → 1.0.10 / 1.1.1 / 1.2.1 で修正
PyPI の brotli 上流 C コードを同梱する束縛 < 1.2.1 が影響 → 1.2.1 以上へ
PyPI の brotlicffi 同じ C ライブラリへの CFFI 束縛 < 1.2.1.0 が影響 → 1.2.1.0 以上へ
npm の brotli 純 JavaScript の別実装 この件では影響しない(部品が別物)

ここでいちばん取り違えやすいのが、名前の似た別物です。npm の brotli パッケージは純 JavaScript の再実装で、上流の C デコーダを持たないため、この件では影響しません。一方、PyPI の brotli・brotlicffi は C 束縛なので影響します。「Brotli という名前のパッケージ」でひとくくりにできない、というのが Python 側の最初のポイントです。

なぜ依存スキャナがこのCVEを取りこぼしたか

ここが本題です。pip-audit・Dependabot・Safety のような依存スキャナは、インストールされているパッケージの「レジストリ名+版」を、勧告データベースの「パッケージ名+影響版域」と突き合わせて判定します。pip-audit は PyPI/OSV 系(PYSEC・GHSA のミラー)を、Dependabot は GitHub Advisory Database を、Safety は自前の DB を見ます。いずれも照合の鍵はレジストリ上のパッケージ名です。

WHY SCANNERS MISS ITスキャナが見逃す仕組み

スキャナは レジストリ名で照合 する。紐付く前は素通りした

PyPI 名に紐付く前(〜10/22)

CVE は上流リポ google/brotli 名義

  • pip-audit・Dependabot・Safety に合致する項目なし
  • 脆弱な brotli==1.2.0 が入っていても「クリーン」
  • クリーン=『合致する勧告が無い』で、無害の証明ではない

PyPI 名に紐付いた後(10/22〜)

GHSA/PYSEC が PyPI 名+版域に紐付け

  • brotli < 1.2.1・brotlicffi < 1.2.1.0 で合致
  • pip-audit が 1.2.0 を検知(当サイト実測)
  • ただしスキャナ側 DB の更新が前提になる
出典: GHSA-9v8h-qqgm-4m35、PYSEC-2026-4322(pip-audit 2.10.1 の出力で確認、2026-10-25)

問題は、CVE-2026-111497 が当初、上流リポジトリ google/brotli を主語に登録され、PyPI の brotli・brotlicffi という名前には紐付いていなかったことです。スキャナから見れば、照合すべき「PyPI パッケージ名の勧告」が存在しない状態です。だから、脆弱な brotli==1.2.0 がインストールされていても、スキャンは合致する勧告を見つけられず、結果として「問題なし」を返しえました。PyPI 名に紐付く GHSA-9v8h-qqgm-4m35 が 2026-10-22 に公開されて初めて、照合できる形になったのです。

ここで確認コマンドの落とし穴

スキャナの「クリーン」は、「合致する勧告が無い」という意味であって、「無害である」という証明ではありません。紐付けの遅れや、勧告 DB の未更新があれば、脆弱なまま「クリーン」が出ます。陽性(検知)でも別経路の露出までは見ていないことがあり、陰性(クリーン)でも DB が古ければ危ない、という両面を分けて読む必要があります。

この「レジストリ名でしか照合できない」性質は、Brotli に限りません。上流の C/C++ ライブラリを同梱する束縛パッケージ全般に共通する盲点です。native な部品そのものの版ではなく、それを包んだパッケージの版でしか勧告が書けません。そのため勧告が各レジストリ名に紐付くまでのあいだ、CVE は存在するのにスキャナは静かなままになります。今回の brotli・brotlicffi は、幸いパッケージの版が同梱 C 版とそろって動くので、< 1.2.1 のような版域で正しく書けました。だからこそ、紐付けさえ済めば pip show の版がそのまま有効な手がかりになります。

自分の環境を確認して直す

確認は版の比較が中心です。コンテナ・CI・本番でそれぞれ別の Python 環境が入るので、環境の数だけ見ます。

WHAT TO DO確認と対策

版を直に見て、DB を最新にした スキャナで照合する

  1. 1.pip show で版を直に見る

    brotli が 1.2.1 以上・brotlicffi が 1.2.1.0 以上か。版=同梱 C 版

  2. 2.pip-audit は DB を最新にして回す

    勧告が入った後でないと検知しない。古い DB のクリーンは当てにしない

  3. 3.lock ファイルで固定版を確認

    requirements.txt・poetry.lock・Pipfile.lock に残る旧版を洗い出す

  4. 4.修正版へ上げる

    brotli 1.2.1 / brotlicffi 1.2.1.0 以上。間接依存も含めて更新する

出典: GHSA-9v8h-qqgm-4m35、PyPI の brotli/brotlicffi、pip-audit 実測(2026-10-25)
# 入っている Brotli 束縛の版を直に見る(brotli 1.2.1 以上・brotlicffi 1.2.1.0 以上なら対応済み)
pip show brotli brotlicffi

# 配布されている版の一覧(最新版がどこか)を確認する
pip index versions brotli

# lock ファイルに固定された旧版を洗い出す(あるものだけ grep される)
grep -rniE "brotli(cffi)?[^a-z]" requirements*.txt poetry.lock Pipfile.lock 2>/dev/null

pip-audit を併用するなら、勧告 DB を最新に取り直してから回します。これは判定ではなく構成の確認で、この結果だけで安全とは言い切れません。間接依存(別のライブラリが内部で brotli を引いている)や、自前で C 版を同梱している配布物までは、この数行では拾い切れないからです。確実なのは、各環境で brotli を 1.2.1 以上・brotlicffi を 1.2.1.0 以上へ上げ切ることです。

当サイトで確かめたこと(2026-10-25)

使い捨ての仮想環境に brotli==1.2.0(影響範囲 1.0.3〜1.2.0 の内側)を入れ、pip show brotli が 1.2.0 と表示することを確認しました。その環境に pip-audit 2.10.1 を回すと、PYSEC-2026-4322 と GHSA-9v8h-qqgm-4m35 の2件で 1.2.0 を指摘し、修正版として 1.2.1 を示しました(陽性対照)。次に brotli==1.2.1 へ上げて同じ pip-audit を回すと No known vulnerabilities found を返しました(陰性対照)。これは勧告が PyPI 名に紐付いた後の状態で、紐付け前のスキャナが静かだった、という本文の主張は実機の前後ではなく時系列(勧告公開日)から導いています。脆弱性を発動させる細工した Brotli データは一切作っていません。

影響範囲:Brotliを復号するPythonアプリ

最後に、どこが露出しうるかです。Node.js のときと同じ問いで、「攻撃者が内容に影響できる Brotli データを、アプリが復号するか」が分かれ目です。Python では、brotli・brotlicffi を直接使って受信データを展開している箇所のほか、これらを内部で引く HTTP クライアントやサーバーのミドルウェア(Brotli の Content-Encoding: br を自動展開する構成)が入口になりえます。直接 import brotli していなくても、依存の依存として入っていることがあるので、pip show と lock ファイルの両方で間接依存まで見ます。

影響の重さは、復号を担うプロセスの権限で変わります。Brotli を復号する処理を特権で動かしている環境ほど、メモリ破壊から波及する範囲は大きくなります。なお実環境での悪用は、公表元の範囲では報告されていません。とはいえ修正は版を上げるだけで軽いので、待つ理由は乏しい、というのが結論です。日頃から依存の更新を回す仕組みはRenovateとDependabotで依存の供給経路を守るにまとめています。今回のようにスキャナが沈黙していても安全とは限らないので、版を直に見る習慣と、勧告 DB を最新に保つ運用の両方が要ります。

参照ソース

・GHSA-9v8h-qqgm-4m35: Out-of-bounds write in the Brotli decoder also affects the PyPI Brotli package(GitHub Advisory) — PyPI の brotli(< 1.2.1)・brotlicffi(< 1.2.1.0)を影響対象として明記・critical(2026-10-25 確認)
・brotli(PyPI プロジェクトページ) — 「Python bindings for the Brotli compression library」・最新版 1.2.1(2026-10-25 確認)
・brotlicffi(PyPI プロジェクトページ) — 「Python CFFI bindings to the Brotli library」・最新版 1.2.1.0(2026-10-25 確認)
・Node.js October 2026 Security Releases(公式ブログ) — CVE-2026-111497 と上流 Brotli の修正版
・Node2shell(Node.js同梱Brotliデコーダの境界外書き込みRCE・当サイト) — 同一 CVE を Node 主役で整理
・HTTP2Shell とは(上流 Brotli の影響範囲・当サイト) — 上流 Brotli を同梱・利用するスタック全般への広がり