Googleが開発する圧縮形式Brotliのデコーダーに、細工した圧縮データを展開するとメモリの境界外へ書き込んでしまう脆弱性(CVE-2026-111497)が見つかりました。Brotliは単体で使うより、Node.js・Pythonのパッケージ・.NET・Linuxのライブラリに組み込まれて動くことが多く、自分のシステムのどこに入っているかを把握しにくい部品です。この記事では、脆弱性の中身、ランタイムごとの修正版、Brotliの版番号では判定できない理由、依存を調べるコマンド、更新までの暫定策を順に整理しました。内容は2026年10月27日時点の公開情報にもとづきます。
まとめ:Brotliを展開する処理から更新し、判定は組み込み先の版で行う
修正版はBrotli本体の1.2.1・1.1.1・1.0.10で、Node.jsは22.23.4・24.22.1・26.12.1、.NETは8.0.33・9.0.22・10.0.14、PythonはBrotli 1.2.1とbrotlicffi 1.2.1.0です。判定は「Brotliの版」ではなく「それを組み込んだランタイムやパッケージの版」で行います。Node.jsもDebianも、Brotliの版番号を上げずに修正だけを取り込んでいるためです。
急ぐべきは、利用者が送る圧縮された本文を自動で展開するAPIと、外部のサーバーから受け取った応答を自動で展開する処理です。どのサービスがBrotliを展開しているか分からない場合は、脆弱性診断・セキュリティ診断で依存と通信経路をまとめて洗い出すと漏れが減ります。
CVE-2026-111497の中身:細工した圧縮データで起きる境界外書き込み
まず、何が壊れていて、どの版が対象かを押さえます。
Brotli 1.0.3〜1.2.0のデコーダーで起きる8バイト領域の書き込み超過
GitHub Advisory DatabaseのGHSA-9v8h-qqgm-4m35によると、不具合はBrotliのC言語実装のデコーダー(c/dec/decode.c)にあります。影響は1.0.3以上1.2.0以下の全プラットフォームです。Node.jsの10月21日のセキュリティ告知は原因をもう少し具体的に書いています。不正なブロック切り替えを「入力が足りない」という一時的な状態として扱い、形式エラーとして止めなかったため、ストリーム展開がデータを追記し続け、内部の8バイトのバッファーを越えて書き込むという説明です。
結果として、プロセスの異常終了、メモリ内容の漏えい、リモートからのコード実行が起こりえます。Googleはv1.2.1のリリースを10月21日に公開し、古い系列向けに1.1.1と1.0.10も出しました。発見者としてNode.jsの告知はOpenAI Codex Securityなど3者を挙げています。「Node2Shell」「HTTP2Shell」という呼び名も出回っていますが、指しているのは同じCVEです。同じ月に公表されたPHP2Shell(CVE-2026-109618・109619)とは別物なので、社内の連絡では番号で区別してください。
CVSS v4.0で9.2、Node.jsはHigh:評価の食い違いと悪用状況
深刻度は発表元で揃っていません。番号を付けたGoogleはCVE.orgのレコードでCVSS v4.0を9.2(Critical)とし、Node.jsの告知はHigh、Microsoftは.NET向けの勧告でCVSS v3.1を8.1としました。Microsoftの評価は攻撃の難しさを「AC:H」と置いていて、既定の設定では展開が動かないという.NETの事情を反映しています。v4.0の値の読み方はnginxのCVSS v4.0 9.2の読み方、v3.1の計算はCVSSv3の計算式とスコアの目安で確認できます。
悪用の状況は、2026年10月26日に発行されたJPCERT/CCの注意喚起(JPCERT-AT-2026-0034)に記載がありません。10月26日版のCISAのKEVカタログにも、このCVEは載っていませんでした。ただし修正のコミットは公開されており、差分から手口を読み取れる状態です。
影響を受ける組み込み先:Node.js・Python・.NET・Linuxの修正版一覧
Brotliを直接使っていなくても、ランタイムやHTTPクライアントが内部で呼んでいれば対象になります。
ランタイムとパッケージ別の影響範囲と修正版(2026年10月27日時点)
公式の告知とセキュリティトラッカーで確認できた修正版を並べます。
| 組み込み先 | 修正版 | 修正の公表 | 出典 |
|---|---|---|---|
| Brotli本体(C) | 1.2.1/1.1.1/1.0.10 | 10月21日 | |
| Node.js | 26.12.1/24.22.1/22.23.4 | 10月21日 | Node.js |
| Python Brotli | 1.2.1 | 10月22日 | PyPI |
| Python brotlicffi | 1.2.1.0 | 10月22日 | GHSA |
| .NET 8/9/10 | 8.0.33/9.0.22/10.0.14 | 10月25日 | Microsoft |
| Debian 12 | 1.0.9-2+deb12u1 | 10月26日まで | Debian |
| Debian 13 | 1.1.0-2+deb13u1 | 10月26日まで | Debian |
| Amazon Linux 2023 | ALAS2023-2026-3334 | 10月24日 | AWS |
.NETの値はMicrosoftの勧告(dotnet/announcements #494)、DebianはDebianのセキュリティトラッカー、Amazon LinuxはALASのCVEページから取りました。.NET Frameworkは対象外と明記されています。一方、Amazon Linux 2023のnodejs20パッケージは「No Fix Planned」で、修正は出ません。JPCERTはBunも影響を受ける製品に挙げていますが、修正版の番号はBunの公式告知で確認できなかったため、表には入れていません。
攻撃が届く2つの通信経路:外部の応答の展開と圧縮された受信本文
Brotliのライブラリが入っているだけでは攻撃は成立しません。攻撃者が用意した圧縮データを、アプリが展開したときに初めて不具合が動きます。経路は大きく2つです。
1つ目は外向きの通信です。HTTPクライアントが応答のContent-Encodingを見て自動で展開する場合、攻撃者が管理するサーバーや乗っ取られた取引先のAPIから細工した応答を返せば届きます。2つ目は内向きの通信で、Content-Encoding: brの付いたリクエスト本文をフレームワークが自動で展開する場合です。Expressのexpress.json()が使うbody-parserは、READMEで「gzip、br、deflate、zstdを自動で展開する」と書いています。ログイン不要のAPIがこれを受けていれば、1回のリクエストで届く構造です。
影響の確認手順:ランタイムと依存のBrotliをコマンドで調べる方法
確認はランタイムごとに見る場所が違います。ここが判定を誤りやすいところです。
Node.jsの判定基準:process.versions.brotliと本体の版の違い
Node.jsはprocess.versionsで同梱ライブラリの版を返し、そこにbrotliの項目もあります。ところが24.22.1のリリースノートを見ると、修正は「deps: brotli: cherry-pick 0ed4268a…」という修正コミットの取り込みで、Brotliを1.2.1へ上げる形ではありません。同梱ライブラリの版表示が修正の有無を表すとは限らないので、判定はNode.js本体の版で行います。
# 実行中の Node.js の版(本番と同じ実行環境で確認する)
node -p "process.version + ' brotli=' + process.versions.brotli"
# 判定:v26.12.1 / v24.22.1 / v22.23.4 以上なら修正済み。
# 20系以前は修正版が出ていないため、22系以降への移行が必要
Node.js 20系は既にサポートが終わっており、告知はEOLの版を「常に影響を受ける」と扱っています。10月の他の9件の修正やLTSの移行日程はNode.jsの脆弱性と10月リリースの更新手順にまとめています。
Pythonの確認軸:brotli・brotlicffiの版とurllib3の展開処理
Pythonでは、PyPIのBrotliとbrotlicffiの2つが同じCのデコーダーを抱えています。確認するのは、この2つの版と、HTTPクライアントが実際に使うかどうかです。
# 入っているか、版はいくつか(Brotli 1.2.1 / brotlicffi 1.2.1.0 以上なら修正済み)
python -m pip show brotli brotlicffi
# urllib3 が br を受け取る設定になっているか
python -c "import urllib3.util.request as r; print(r.ACCEPT_ENCODING)"
# どのパッケージが brotli を引き込んでいるか
python -m pip show brotli | grep -i "Required-by"
urllib3 2.8.0のソースを2026年10月27日に読んだところ、brotlicffiかbrotliがimportできるときだけbr用のデコーダーが有効になり、送信するAccept-Encodingにもbrが加わる作りでした。Brotliを入れていない手元の環境(Python 3.14.7)では、2つ目のコマンドが「gzip,deflate,zstd」を返すことを確認しています。展開するかどうかは応答側のContent-Encodingで決まるので、送信ヘッダーからbrを外しても防げません。requestsはurllib3を使うので同じ扱いです。
見落としやすいのが、urllib3がBrotliDecoderの中で「解凍爆弾を防ぐにはBrotli 1.2.0以上が必要」という警告を出す点です。この警告に従って1.2.0へ上げた環境は、ちょうど今回の影響範囲に入っています。
.NETはランタイム版と、Brotliを展開する4つの処理をコードから探す
.NETは、ランタイムが修正版かどうかと、アプリが実際に展開しているかの2点を見ます。Microsoftの勧告は、ASP.NET Coreの受信本文の展開もHttpClientの自動展開も既定では有効でないとしています。対象になるのは、自分で有効にしたコードがある場合です。
# インストール済みランタイムの版(8.0.33 / 9.0.22 / 10.0.14 以上なら修正済み)
dotnet --list-runtimes
# Brotli を展開しうるコードの洗い出し
grep -rnE "AddRequestDecompression|AutomaticDecompression|BrotliStream|BrotliDecoder" --include=*.cs .
AutomaticDecompressionにBrotliかAllを指定している行、AddRequestDecompressionでbrを受け付けている行が、信頼できない相手のデータを扱っていないかを確かめます。NativeAOTや自己完結型で配布したアプリは、サーバーの共有ランタイムを更新しても直りません。修正版のSDKで発行し直す必要があります。
Debian・Amazon LinuxのlibbrotliはOSの修正版番号で判定する
Linuxのパッケージは、ディストリビューションが修正を古い版へ移植して配布します。Debian 12の修正版は「1.0.9-2+deb12u1」で、上流の版番号は1.0.9のままです。上流の影響範囲(1.0.3〜1.0.10未満)と照らすと対象に見えますが、末尾の+deb12u1が付いていれば修正済みです。
# Debian / Ubuntu
dpkg-query -W libbrotli1
# Amazon Linux 2023
rpm -q brotli
dnf updateinfo list --cve CVE-2026-111497
Debianのトラッカーは、Debianが配布するnodejsとpython-brotlicffiがシステムのBrotliを使うと注記しています。逆に、nodejs.orgの公式バイナリや公式Dockerイメージ、pipで入れたwheelは自前のBrotliを持つため、OSのlibbrotliを更新しても直りません。コンテナをTrivyでスキャンする運用やOSV-Scannerでの依存の点検では、OSパッケージとランタイム・言語パッケージの結果を別々に見てください。
更新手順と更新までの暫定策:受信本文と外部応答の展開を止める設定
多くの環境はランタイムかパッケージを上げれば終わります。すぐ上げられない場合の手当ても書いておきます。
requirementsとpyproject.toml:Python依存の下限1.2.1
更新後に古い版へ戻らないよう、依存の定義に下限を書きます。brotliを直接書いていなくても、requestsやaiohttpの追加機能(extra)経由で入っていることがあるので、下限は明示しておくのが確実です。
# requirements.txt
brotli>=1.2.1
brotlicffi>=1.2.1.0 # brotlicffi を使っている場合のみ
# pyproject.toml(PEP 621 形式)
[project]
dependencies = ["brotli>=1.2.1"]
Node.jsはDockerfileのベースイメージを「node:24.22.1」のように修正版以上へ上げ、.NETは修正版のSDKで発行し直します。勧告のたびに更新PRを受け取る設定はdependabot.ymlの書き方を参考にしてください。
Expressのinflateと.NETのbr設定を外す暫定策と、その副作用
更新を待つ間は、信頼できない相手の圧縮データを展開しないことが唯一の手当てです。Microsoftの勧告も同じ方針で、既存の設定からBrotliだけを外し、gzipとdeflateは残すよう書いています。
// Express:圧縮された受信本文の自動展開を止める
app.use(express.json({ inflate: false }));
// .NET:HttpClient の自動展開から Brotli を外す
var handler = new HttpClientHandler {
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
body-parserのREADMEのとおり、inflateをfalseにすると圧縮された本文は展開されずに拒否されます。圧縮して送ってくる正規の利用者がいれば、その送信も失敗します。ログで受信時のContent-Encodingを数え、影響を確かめてから入れてください。Microsoftは、今使っていない展開の設定を新たに足すことも避けるよう書いています。
対応の優先順位:外部の圧縮データを展開するサービスから更新する基準
複数のサービスがある場合の順番を、条件ごとに言い切ります。
即日更新が要る構成と定例更新に回せる構成:外部データの展開による線引き
当日中に更新するのは、ログイン不要の公開APIで圧縮された受信本文を自動展開しているNode.jsのサービスと、外部のURLを取りに行って応答を展開する処理です。後者には、Webページの取得、Webhookの送信先からの応答の読み取り、利用者が指定したURLの画像やRSSの取り込みが当たります。受信側の守りを固める考え方はAPI不正アクセス対策の実装手順と共通です。
週内でよいのは、取引先など限られた相手とだけ通信するバッチです。自社で圧縮したデータしか展開しない処理、.NETで展開の設定を一度も有効にしていないアプリは、次の定例更新に回して構いません。ただし、どの処理が外部のデータを展開しているかを即答できないなら、すべてを当日扱いにするのが安全です。依存と通信経路の棚卸しを毎回の勧告で回せる体制を作るなら、脆弱性診断の進め方と外注時の判断基準から全体像をつかむのが近道です。
NativeAOT・単一実行ファイル・コンテナは作り直すまでが対応
見落としやすいのは、ランタイムを中に抱えて配布したものです。.NETのNativeAOTと自己完結型、Node.jsのSEA(単一実行ファイル)、ランタイムを含めて作ったコンテナイメージは、サーバー側でNode.jsや.NETを更新しても中身が変わりません。修正版で作り直して配り直すまでが対応範囲です。
コンテナは、ベースイメージのタグを更新しても、そのタグから作ったアプリのイメージを再ビルドしなければ古いままです。レジストリに残る過去のイメージから本番へ戻す手順がある場合は、戻し先のイメージも修正版で作り直しておきます。
Brotliの脆弱性CVE-2026-111497でよくある質問と回答
CVE-2026-111497への対応で出てきやすい疑問に、公開されている一次情報の範囲で答えます。
WebサーバーでBrotli圧縮を有効にしているだけでも影響しますか?
今回の不具合はデコーダー(展開する側)にあります。nginxやApacheで応答をBrotliで圧縮して返しているだけなら、サーバーが圧縮データを展開する処理は動きません。影響するのは、受け取った圧縮データを展開する側です。同じサーバーで動くNode.jsやPythonのアプリが受信本文や外部の応答を展開しているかは、別に確認してください。
Node.js 20を使い続ける場合の対処法はありますか?
20系向けの修正版は出ていません。Node.jsの告知はサポート終了済みの版を常に影響ありと扱っています。Amazon Linux 2023のnodejs20パッケージも修正予定なしです。移行までの間は、受信本文の展開を止め、外部の応答を展開する処理を減らしたうえで、22系以降への移行を急いでください。
ブラウザーも更新が必要ですか?
ブラウザーはWebサーバーから受け取ったBrotliを日常的に展開しますが、今回の勧告に主要ブラウザーの名前はありません。Amazon LinuxのCVEページでもfirefoxは「Not Affected」です。ブラウザーは通常の自動更新を続けていれば十分で、優先して見るべきはサーバー側で動くランタイムとライブラリです。
Pythonでbrotliを入れた覚えがない場合でも確認が要りますか?
要ります。brotliはrequestsやaiohttp、httpxの追加機能として一緒に入ることがあり、自分でインストールした記憶がなくても環境に存在する場合があります。本文の「pip show」で入っているか、どのパッケージが引き込んだかを確かめてください。入っていなければurllib3はbrを展開しないので、このCVEの経路にはなりません。
攻撃でメモリの情報が漏れた場合、報告は必要ですか?
このCVEでは、展開した処理のメモリ内容が漏れるおそれがあると説明されています。漏れたメモリに個人データが含まれ、漏えいのおそれがあると判断した場合は、個人情報保護委員会への報告の対象になりえます。判断の基準と期限の確認先は、個人情報保護委員会への報告義務と速報3〜5日の実務です。
関連記事
- 脆弱性とは?種類・CVE/CVSSの仕組みと発見から修正までの実務を解説:勧告の公表から修正までの流れの基礎です。
- CVE(共通脆弱性識別子)とは?番号の読み方・CVSS/CWE/NVDとの違いと調べ方:GHSA番号とCVE番号の関係を整理しています。