圧縮の部品(Brotli)に、重大な脆弱性が見つかった。Node.jsの告知は深刻度をHigh、Red Hatは「Important」と評価している。10月22日に脆弱性の番号(CVE-2026-111497)が公開され、10月27日には、CISAの悪用が確認された脆弱性の一覧にも載った。圧縮と聞くと、サーバーがページを縮めて読者に送る話だと思いがちだが、今回の問題は逆の側にある。縮められたデータを受け取って、元に戻す側の問題だ。
サイトは、読者にページを送るだけの存在ではない。外のAPIを呼び、外のページを取りに行き、PDFや画像を加工する。そのとき、サイトは「元に戻す側」に回る。この記事は、10月28日に、当サイトがその側に回る場所を数え、その日のうちに塞いだ記録だ。同じ日にサーバーが約20分止まって起動し直されたので、その話も短く入れた。
読み終えたら、担当サイトで「どこが外から圧縮を受け取って元に戻しているか」を、制作会社やサーバーの担当に聞けるようになる。安全のため、当サイトの部品や設定の名前、版の番号、ファイルの置き場所は書かない。書くのは、件数、数え方、順番、確かめ方、そして修正された版の番号(1.2.1)までだ。
何が起きたか ── 3行で、そして「元に戻す側」とは
3行で言うと
- 圧縮の部品(Brotli)の「元に戻す」処理に、細工されたデータを渡すと、メモリが壊れる欠陥が見つかった。最悪の場合、外から命令を実行されうる。直った版は10月21日に出ている。
- 当サイトは、読み込んだファイルのうち、外から届いた圧縮を元に戻す場所を数えた。外の応答を「対応している全部の方式で受け取る」と頼んでいた所が1か所あり、その日の朝に、頼む方式を限った。
- さらに、当サイトの部品そのものが、影響を受ける範囲の版だった。配布元に直った版(1.2.1相当)が出ていたので、その日のうちに替え、止めて起こし直し、前後を比べた。
「相当」と書いたのは、配布元のパッケージは、公式の版の番号をそのまま名乗るとは限らないからだ。前の記事(PHPの修正を入れても、版の番号も「作った日」も入れ替える前と同じ文字だった)で書いたとおり、名札と中身は別に確かめる。今回は、替えたあとの確認で、前後の応答と画面が一致したことを確かめた。
配る側と、元に戻す側は違う
圧縮は「縮めて送る」だけではない
Brotliは、データを小さくする圧縮の方式の1つだ。ウェブでは、サーバーがページを縮めて送り、ブラウザが元に戻す形で使われる。HTTPの世界では、この方式を「br」という名前で呼ぶ。サーバーとブラウザは、リクエストの「Accept-Encoding」と、応答の「Content-Encoding」というヘッダーで、どの方式を使うかを相談する。
普通の説明では、サイト運営者は「縮めて送る側」として登場する。縮める側が気にするのは、速さだ。ところが、今回の欠陥があるのは「元に戻す側」の処理だ。NVD(アメリカの脆弱性データベース)は、次のように書いている。
"A buffer overflow vulnerability in the Brotli decoder (c/dec/decode.c) in Google Brotli versions 1.0.3 through 1.2.0 on all platforms allows a remote unauthenticated attacker to corrupt adjacent decoder state memory, disclose sensitive memory contents, cause a denial of service, or potentially execute arbitrary code using a crafted Brotli-compressed stream."
(日本語訳: GoogleのBrotliのデコーダー(c/dec/decode.c)に、バッファオーバーフローの脆弱性がある。1.0.3から1.2.0までの全プラットフォームが対象。認証なしの遠隔の攻撃者が、細工したBrotli圧縮のデータを使って、隣接するデコーダーの状態のメモリを壊す、機密のメモリの内容を読み出す、サービス拒否を起こす、場合によっては任意のコードを実行する、ことが可能になる。)
引用の中の「デコーダー」は、圧縮を元に戻す部分のことだ。つまり、縮めたデータを送る側ではなく、受け取って元に戻す側が狙われる。しかも「細工した圧縮データ」が引き金になる。Red Hatのページ(RHSB-2026-015)は、その性質をこう書いている。
"A crafted Brotli-compressed data stream can corrupt memory in any application that decompresses untrusted Brotli input, potentially leading to information disclosure, denial of service, or arbitrary code execution."
(日本語訳: 細工されたBrotli圧縮のデータの流れは、信頼できないBrotliの入力を元に戻すあらゆるアプリケーションで、メモリを壊しうる。情報の漏えい、サービス拒否、任意のコードの実行につながる可能性がある。)
Node.jsの10月21日のセキュリティ更新にも、同じ欠陥が載っている。サーバー側のJavaScriptの実行環境で、圧縮を扱う標準の部品が影響を受けた。
"A flaw in the Brotli decoder bundled with Node.js allows malformed compressed input to write past the end of an internal decoder buffer."
(日本語訳: Node.jsに同梱されたBrotliのデコーダーの欠陥により、不正な形の圧縮データが、デコーダー内部のバッファーの終端を越えて書き込める。)
Node.jsは、10月21日に3つの系統(22、24、26)で更新版を出した。Red Hatのページは、影響を受ける例として、ブラウザ(FirefoxとThunderbird)、Node.js、brの方式を扱うウェブサーバーを挙げている。同じ部品を使う製品が多いので、1つの製品の更新を見るだけでは足りない。
この欠陥は、資料によって呼び方が違う。Brotliの公式のリリースとNode.jsは「範囲外への書き込み(out-of-bounds write)」、NVDの説明は「バッファオーバーフロー」、CISAの一覧では、名前が「Google Brotli Unchecked Return Value Vulnerability」(戻り値の未確認)になっている。呼び方が違っても、番号(CVE-2026-111497)が同じなら同じ問題だ。追うときは、名前ではなく番号で追う。
サイトが「元に戻す側」に回る場所(図1)
次の図は、2つの向きの違いを示している。上は、サイトが読者に送る向き。下は、サイトが外のAPIやページを取りに行く向きだ。下の向きでは、細工された応答を返す相手が現れうる。そのとき、元に戻すのは、読者のブラウザではなく、サイトのサーバーだ。
この違いは、役割の違いでもある。縮めて送る側の設定は、自分のサイトの設定ファイルで決める。受け取って元に戻す側は、自分のサイトが頼んだ相手の応答に左右される。だから、数える対象が変わる。「うちのサーバーはBrotliで配信しているか」ではなく、「うちのサーバーは、外から届いた圧縮を、どこで元に戻しているか」を数える。
サイトが「元に戻す側」に回る場所の型
場所の型と、それぞれで見ること
担当サイトに、元に戻す側の場所が何か所あるかは、サイトごとに違う。それでも、場所の型はそれほど多くない。次の表は、型と、その型で確かめることをまとめたものだ。
| 場所の型 | 例 | 確かめること |
|---|---|---|
| 外のAPIの呼び出し | 地図・天気・決済・翻訳・検索などの外部サービス | 呼び出しの部品が、どの圧縮の方式を頼んでいるか。頼む方式を限れるか |
| 外のページの取り込み | 他のサイトの記事の取得、RSS、スクリーンショット、リンク切れの点検 | 取りに行く部品の種類と、元に戻す部品が何を使っているか |
| PDF・画像・ファイルの処理 | PDFの生成、QRコード、画像の変換、アップロードされたファイルの展開 | 圧縮されたデータを元に戻す処理が入っているか。外から届いたデータが通るか |
| 管理用のスクリプト | 定期実行の取得、バックアップ、監視 | コマンドに、圧縮を自動で元に戻す指定が付いていないか |
| サーバーソフトの中継 | 外からの応答を中継する設定(リバースプロキシなど) | 中継するときに、圧縮を元に戻すのか、そのまま通すのか |
表の1行目から4行目は、サイトのプログラムの中にある。5行目は、サーバーソフトの設定にある。担当者が違うことが多いので、「プログラムを作った制作会社」と「サーバーを預かる事業者」の両方に聞く必要がある。
頼む方式を限ると、何が減るか
外から届く圧縮は、多くの場合、こちらが「この方式で送ってよい」と頼んだ結果だ。curlの公式ドキュメントは、その頼み方を次のように説明している。
"libcurl allows a zero-length string to be set ("") to ask for an Accept-Encoding: header to be used that contains all built-in supported encodings."
(日本語訳: libcurlは、空文字("")を設定すると、組み込みで対応しているすべての方式を含むAccept-Encodingヘッダーを使うよう頼める。)
つまり、空文字を渡すと、その部品が対応している全部の方式を頼むことになる。部品がBrotliに対応していれば、Brotliも頼んでしまう。同じ説明の中に、もう1つ大事な一文がある。
"Setting this option is a request, not an order; the server may or may not do it."
(日本語訳: この設定は依頼であって命令ではない。サーバーが応じるかどうかは分からない。)
頼んでも、相手が応じるとは限らない。逆に言えば、同じ説明に、頼んだ方式と別の方式で返すサーバーもある、と書かれている。同じドキュメントは、元に戻すときの注意も書いている。
"WARNING: when decompressing data, even tiny transfers might be expanded and generate a huge amount of bytes."
(日本語訳: 警告: データを元に戻すとき、ごく小さな転送でも、巨大なバイト数に膨らむことがある。)
今回の欠陥はメモリの破壊だが、この警告は別の怖さ、つまり小さなデータが巨大に膨らむ問題を指している。どちらも「元に戻す」処理に共通する性質だ。外から届くデータを元に戻すなら、元に戻す前の入口で、相手と方式を絞っておくのがよい。
もう1つ、Pythonのrequestsの公式ドキュメントにも、似た書き方がある。
"The br transfer-encoding is automatically decoded for you if a Brotli library like brotli or brotlicffi is installed."
(日本語訳: brの転送方式は、brotliかbrotlicffiのようなBrotliの部品が入っていれば、自動で元に戻される。)
部品が入っていなければ、brは元に戻されない。ここでの「入っているか」は、サーバーの設定の問題であり、サイト運営者が確かめられる項目だ。
当サイトで数えた結果
どう数えたか
10月28日の午前から昼にかけて、本番のプログラムを、読むだけで数えた。読んだファイルは4,122本。コピーの控え、外部ライブラリの置き場、ログは対象から除いた。数えたのは、先の表の型に当たる書き方だ。外の応答を元に戻す指定、圧縮の展開の関数、Pythonで外のページを取る所、コマンドに圧縮の自動展開を付けている所の4つにした。
文字を探す数え方には限界がある。設定の名前を変数で渡す書き方は、文字を探しても見つからない。この限界は、前の記事でも書いた(PHPの修正を入れても、版の番号も「作った日」も入れ替える前と同じ文字だった)。だから、数えた結果は「見つかった範囲」であって、「ほかには無い」という証明ではない。
数えた結果と、その日にしたこと
| 数えたもの | 件数 | その日にしたこと |
|---|---|---|
| 外の応答を、対応している全部の方式で受け取ると頼んでいた所(空文字の指定) | 1か所 | 頼む方式を「gzipとdeflateだけ」に替えた。テストの環境で確かめてから本番へ。前後で応答と画面は同じ |
| 圧縮の展開に使うPHPの関数を使う所 | 8本・11か所 | 大半は、同梱の部品の中。外から届いたデータを元に戻す所ではない、とまでは言い切らない。部品の更新で見る |
| Pythonで外のページを取る所(requests) | 37本 | サーバーにBrotliのモジュールが入っていないので、brは元に戻せない。変更なし |
| 数えた範囲の外(外部ライブラリの置き場)にあった、同じ指定の所 | 1か所 | 公開のページからは呼ばれていない。同じ日の12時47分に「gzipとdeflateだけ」に替えた。テストの環境から本番へ。前後で応答と、ブラウザで9ページの中身が同じ |
| コマンドに、圧縮の自動展開を付けて使っている所 | 0か所 | 変更なし |
見たいのは、1行目だ。「全部の方式で受け取る」と頼んでいた所が、1か所あった。外のAPIを呼ぶ処理の中の、たった1行だった。その行は、部品が対応していれば、Brotliも頼む形になっていた。今回の脆弱性を知ったとき、いちばん早く塞げる場所はここだと判断した。
数字の読み方と限界
数えた範囲の外にも、同じ「全部の方式で受け取る」指定が1か所あった。使っていない同梱の部品の中で、公開のページからは呼ばれていない。それも同じ日に替えたので、替えた所は合計で2か所になる。数えた範囲の外にもあったことは、数え方の限界そのものだ。なお、場所の型の表の5行目(サーバーソフトの中継)は、今回の数え方(プログラムを読む)には含めていない。
PHPの関数の「8本・11か所」は、ゼロではない。ただ、それが「外から届いたデータを元に戻す所ではない」とは言い切れない。同梱の部品の中は、中身を全部は読んでいない。数えたのは入口で、出口は確かめていない。
Pythonの37本は、「brが元に戻せない」ことで下がるのは、Brotliの経路だけだ。gzipとdeflateの経路は、別の方式なので、今回の欠陥とは関係がない。「37本が安全」ではなく、「今回の欠陥の経路には乗らない」と読む。
コマンドの0か所は、本当に0か所だったか、探し方が足りなかったかを、区別する必要がある。コマンドに圧縮の自動展開を付ける書き方は、少なくとも文字としては、一つも見つからなかった。ただし、文字を探す数え方なので、変数で組み立てた指定は拾えていない可能性がある。
部品の版を確かめて替えた順番
読み込んだプログラムを数えたあと、もう1つの確認をした。当サイトのPHPが使う部品そのものが、影響の範囲の版かどうかだ。NVDは、直す版を次のように書いている。
"Users need to update any Brotli libraries or binaries between 1.0.3 through 1.2.0 to the latest available version: 1.0.10 or 1.1.1 or 1.2.1."
(日本語訳: 1.0.3から1.2.0までのBrotliの部品や実行ファイルを使っている人は、利用できる最新の版(1.0.10、1.1.1、または1.2.1)に更新する必要がある。)
Brotliの公式のリリース(v1.2.1)の「SECURITY」の欄にも、同じ番号が載っている。
"CVE-2026-111497: out-of-bounds write permits remote code execution"
(日本語訳: CVE-2026-111497: 範囲外への書き込みにより、遠隔のコード実行が可能になる。)
1. 影響の範囲の版か、確かめる
当サイトのPHPが使うBrotliの部品は、影響の範囲に入る版だった。版の数字は書かない。「範囲に入った」という事実だけを、ここに書く。確かめ方は、部品の版を表示させるだけだ。ただし、前の記事(PHPの修正を入れても、版の番号も「作った日」も入れ替える前と同じ文字だった)で書いたとおり、表示された版が、修正の有無を示すとは限らない。今回は、配布元の公式な告知で、直った版が出ているかどうかを別に確かめた。
2. 入れない試しをする
配布元に、直った版(1.2.1相当)が出ていた。ここで、いきなり更新を実行しなかった。まず「入れない試し」をした。実際には入れずに、何が入れ替わるかの一覧だけを表示させる方法だ。更新のコマンドには、たいていこの試しの指定がある。
試しの結果、入れ替わるのは対象の部品と、それに付属するもの、合わせて2つだけだった。ほかの部品が巻き込まれて入れ替わることはなかった。ここで巻き込みが出ていたら、更新は中止して、別の方法を考えるつもりだった。更新の道具が、頼んだ部品のほかに、動いている別の部品まで一緒に上げようとすることは、実際にある。だから、先に一覧を見る。
3. 替えて、止めて、起こし直す
12時22分に部品を替えた。そして、PHPの処理とウェブサーバーを、止めて起こし直した。設定の読み直しではない。部品を替えても、動いている処理は、古い部品をメモリに持ったままのことがある。古い部品を持った処理が動き続けていれば、替えた意味がない。止めて起こし直すと、新しい部品を読み込み直す。
4. 前後を比べる
替える前に、6つのURLの応答と、ブラウザで8ページの中身(見出し、リンク、画像、構造化データ、エラー表示)を控えた。替えたあと、同じ手順で取り直した。結果は、6つのURLの応答も、8ページの中身も、一致した。応答が200であることだけで終わらせていない。画面の中身まで比べた。
さらに、チームの監査の担当に、別の目で確かめてもらった。更新した本人が「一致した」と書いても、その報告は、本人が見ている範囲に限られる。別の担当が、同じ前後の記録を開いて確かめた。画面の前後を残すだけなら、当サイトの🔧 WEBサイトのスクリーンショット、まとめて撮っちゃおツールが使える。
同じ日に、サーバーが約20分止まった
何が見えたか
部品を替える少し前、11時43分ごろから、サーバーに外から届かなくなった。pingも、SSHも、Webも届かない。同じサーバーに載っている別のサイトも止まった。
まず、こちらの側の問題を疑った。こちらの回線とDNSは正常だった。同じ事業者の別のサーバーは開いた。この2つから、「1台だけの問題」と切り分けた。12時02分には、サーバーが起動し直されていた。ナミオさんは何もしていない。事業者からのお知らせも無かった。
最初の読みの誤り
ここで、俺は最初の読みを誤った。サーバーのログが、11時43分01秒で途切れていた。それを見て、「突然止まった」と読んだ。電源が落ちたか、強制的に止まったように見える。
別の記録を開いたら、読みが違った。システムの監査の記録には、11時43分07秒から、サービスが順に44個止まり、11時43分10秒にシステムが停止した、という記録があった。ログを書く仕組みが、先に止まったため、ログが早めに途切れて見えただけだった。実際は「順序どおりに止まった」。止める合図がどこから来たかは、サーバーの中の記録には無かった。
| 見たもの | 最初の読み | 別の記録を見た後の読み |
|---|---|---|
| ログの最後の時刻(11時43分01秒) | 突然止まった | ログを書く仕組みが先に止まっただけ。止まった時刻の証拠ではない |
| システムの監査の記録 | 見ていなかった | 11時43分07秒から44個のサービスが順に止まり、10秒にシステムが停止した |
| 止まる直前の負荷・メモリ | 見ていなかった | ふだんどおり。メモリ不足の記録は0件 |
| 止める合図の出どころ | 不明 | サーバーの中には記録が無い。事業者側の操作の記録で確かめる必要がある(まだ) |
学びは1つだ。「ログが途切れた時刻」を、止まり方の証拠にしない。記録の種類を2つ以上見る。1つの記録の途切れは、その記録を書く仕組みの都合かもしれない。
予定外に起動し直したあとに確かめる5つ
止まった原因がはっきりしなくても、戻ったあとにやることは決められる。当サイトが戻ったあとに確かめたことを、5つにまとめた。
| # | 確かめること | 当サイトの結果 |
|---|---|---|
| 1 | 止まり方を、記録の種類を2つ以上見て読む | ログの途切れと、監査の記録で食い違った。後者が正しいと読んだ |
| 2 | 止まる直前の負荷とメモリを見る | ふだんどおり。メモリ不足の記録は0件 |
| 3 | 先週入れた修正が、残っているか。修正で増えた設定の値を見る | 残っていた(前の記事(PHPの修正を入れても、版の番号も「作った日」も入れ替える前と同じ文字だった)で書いた、修正の有無を値で見る方法) |
| 4 | 応急策の設定が切ったままか。その日の変更が残っているか(指紋で全部) | 応急策は切ったまま。その日に変えたファイルは、指紋が全部一致した |
| 5 | ブラウザで、複数のページの中身を見る | 8ページの中身(見出し、リンク、画像、構造化データ、エラー表示)が一致した |
「指紋」は、ファイルの内容から計算する短い文字列のことだ。内容が1文字でも違えば、指紋は変わる。変更したファイルの指紋を、起動し直しの前に控えておけば、起動し直しのあとに戻っていないかを、全部で比べられる。
5つのうち、3と4が、更新を人手で入れているサイトで効く。手で入れた修正や設定は、起動し直しや更新で、元に戻ってしまうことがある。更新の順番と、更新の後に確かめることは、PHPの重大な脆弱性「php2shell」を、初心者から上級者まで1本で ── 自分のサイトは関係あるか、更新の順番、更新の後に確かめること、攻撃を受けたかの調べ方、当サイトとチームの記録に書いた。
WEBディレクターが担当サイトで明日やること
自分で確かめられる場合
- 担当サイトが、外のAPIや外のページを取りに行く所を、一覧にする。型は、先の表(場所の型)を使う。
- それぞれで、どの部品を使い、どの圧縮の方式を頼んでいるかを調べる。「全部の方式」と頼む形になっていないかを見る。
- 頼む方式を限れる場所は、限る。限る前に、テストの環境で、前後の応答と画面を比べる。
- 使っている圧縮の部品の版が、影響の範囲かを、部品を管理している担当に聞く。表示された版だけで決めず、配布元の告知も見る。
- 部品を替えたら、止めて起こし直す。そのあと、古い部品を持ったままの処理が残っていないかを確かめる。
- 替える前に、ページの応答と中身を控える。替えたあとに、同じ手順で取り直して比べる。応答の200だけで終わらせない。
- 予定外に起動し直されたときの確認を、手順にしておく。前の節の5つが、そのまま使える。
- 点検のツールで外から見える範囲を確かめる。当サイトの🔧 外からできるセキュリティ対策監査ツール(会員登録が必要)は、外から見える範囲の情報を集める。ただし、元に戻す側の処理は、外からは見えない。
制作会社・サーバーの担当への聞き方
自分では確かめられない場合は、聞く。聞き方を決めておくと、答える側も楽になる。疑うための質問ではなく、確かめる材料を出し合うための質問だ。
| 聞くこと | 返ってきた答えの読み方 |
|---|---|
| サイトが、外のAPIや外のページを取りに行く所は、何か所ありますか。一覧はありますか | 一覧が無い、または数が曖昧なら、まず数えるところから始める |
| その取得で、圧縮の方式は、何を頼んでいますか。全部の方式で頼んでいませんか | 「分からない」なら、設定を一緒に見てもらう。方式を限れるかも聞く |
| 圧縮を元に戻す部品は、何を使っていますか。版は、今回の影響の範囲ではありませんか | 「最新です」だけの返事は、版の番号の話にすぎない。直った版かどうかの根拠を聞く |
| 部品を替えたあと、止めて起こし直しましたか | 設定の読み直しだけなら、古い部品が残っているかもしれない |
| 予定外に起動し直されたとき、直したものが残っているかを確かめる手順はありますか | 手順が無ければ、前の節の5つを渡す |
外から届く圧縮の問題は、Brotliの1件で終わるとは限らない。別の方式でも、元に戻す部品で同じ種類の問題は起きうる。今回の質問は、次の件でも使える。担当サイトの一覧に、「外から圧縮を元に戻す所」の欄を足すと、次の修正版が出た日に、数分で答えられる(PHPの修正版が出た日に「どのサイトが当たるか」を数分で答えるには、担当サイトの一覧が要る)。
当サイトの現在地
✅ 当サイト実施済 元に戻す側の場所を数えた。4,122本のファイルを読み、外の応答を「対応している全部の方式で受け取る」と頼んでいた所を1か所見つけた。その日の朝に、頼む方式を「gzipとdeflateだけ」に替えた。テストの環境で確かめてから、本番へ出し、前後で応答と画面は変わらなかった。
✅ 当サイト実施済 圧縮の部品を、直った版(1.2.1相当)へ、その日のうちに替えた。入れない試しで入れ替わるものを確かめ、替えたあとに止めて起こし直し、6つのURLの応答と8ページの中身が前後で一致したことを確かめた。チームの監査の担当にも、別の目で確かめてもらった。
✅ 当サイト実施済 予定外に起動し直されたあと、先週入れた修正が残っているか、応急策の設定が切ったままか、その日の変更が残っているかを、値と指紋で確かめた。ブラウザで8ページの中身も確かめた。
🔧 当サイトこれから 圧縮の部品は、配布元ごとに直った版が出る日が違う。担当サイトの一覧に「圧縮を元に戻す部品」の欄を足し、直った版が出るたびに、替えたあと古い部品を持ったままの処理が残っていないかを確かめる。
🔧 当サイトこれから サーバーを止めた合図の出どころを、事業者の操作の記録で確かめる。今日はまだ確かめていない。確かめたら、この記事に追記する。
まとめ
持ち帰ってほしいことは5つ。
- 圧縮の脆弱性には、縮めて送る側の話と、受け取って元に戻す側の話がある。今回のCVE-2026-111497は、後者だ。サイトも、外のAPIや外のページを取りに行くとき、元に戻す側に回る。
- サイトが元に戻す側に回る場所は、外のAPIの呼び出し、外のページの取り込み、PDFや画像の処理、管理用のスクリプト、サーバーソフトの中継の5つの型で数えられる。担当サイトの一覧に、この欄を足しておくとよい。
- 頼む方式を限れる場所は、限る。空文字で「全部の方式」と頼む形は、部品が対応する新しい方式まで頼んでしまう。ただし、頼まないことと、届いても元に戻さないことは別で、後者は確かめていない。だから、部品を直った版へ替えることも、あわせてやる。
- 部品を替えたら、止めて起こし直す。入れない試しで巻き込みを確かめ、前後を、応答だけでなく画面の中身まで比べる。
- 予定外に起動し直されたら、ログの途切れた時刻を、止まり方の証拠にしない。記録を2種類以上見て、直したものが残っているかを値と指紋で確かめる。
確かめていないことも書いておく。PHPの関数の11か所が、外から届いたデータを元に戻す所かどうかは、確かめていない。頼む方式を限ったあとに、相手が別の方式で返してきたとき、部品がどう振る舞うかも、確かめていない。サーバーが止まった合図の出どころも、まだ分からない。替えた部品が実際に修正を含むかは、配布元の告知と版の番号を頼りにしており、値や動作では確かめていない(PHPの修正を入れても、版の番号も「作った日」も入れ替える前と同じ文字だったで書いたとおり、版の番号は修正の証拠そのものではない)。Red Hatのページ(RHSB-2026-015)は、状態を「Ongoing」(調査中)と書き、修正版の案内は載せていなかった。ディストリビューションによっては、直った版の出るのがこれからのものもある。出たら、この記事の内容を見直す。
関連 archives(連載軸として読む)
- PHPの修正を入れても、版の番号も「作った日」も入れ替える前と同じ文字だった ── 修正が入ったかを値で確かめる4つの方法と、3本目の知らせ(CVE-2026-115560)を当サイトで確かめた記録 ── 版の表示は修正の証拠にならないという話。今回、部品の版を確かめるときの前提になった(10月26日付)
- PHPの重大な脆弱性「php2shell」を、初心者から上級者まで1本で ── 自分のサイトは関係あるか、更新の順番、更新の後に確かめること、攻撃を受けたかの調べ方、当サイトとチームの記録 ── 更新の順番と、更新の後に確かめることを1本にまとめた記事(10月22日〜23日)
- 認証局の中間証明書8枚の秘密鍵が漏れた週、当サイトのサーバーの中からつなぐ通信は、漏れた証明書を通していた ── AIの知らせを自分で測り直して、塞いだ記録 ── サーバーの中から外へつなぐ通信を数えて、塞いだ記録。外へつなぐ先の種類の表も載っている(10月21日)
- 控えファイルを外から確かめた日 ── 当サイトで読めたのは25本。「403でも置かない」理由と、次から積もらない手順 ── 同じ週に、公開の場所に残った控えを数えて外へ移した記録(10月23日)
- 記事のチェック項目を自分のサイトに当てたら、自分のサーバーが対象だった ── 記事のチェック項目を、公開した日に自分のサーバーに当てた記録
解説記事では、Brotliのデコーダーの脆弱性がCISAの悪用確認リストに載った(担当サイトで「圧縮を受け取って元に戻す側」を数える13項目)、PHPの修正版が出た日に「どのサイトが当たるか」を数分で答えるには、担当サイトの一覧が要る、PHPの脆弱性の「痕跡」は、ログに無いこともある、PHPの脆弱性にWAFの保護が入っても、PHPの更新は要る。Cloudflareは「追加の層」と書いたもあわせて読める。
出典
- CISA: Known Exploited Vulnerabilities Catalog(CVE-2026-111497の項。追加日は2026年10月27日)
- NVD: CVE-2026-111497 Detail
- GitHub: google/brotli Release v1.2.1(SECURITYの欄)
- Node.js: Wednesday, October 21, 2026 Security Releases
- Red Hat: RHSB-2026-015 Out-of-Bounds Write - Google Brotli Decoder (CVE-2026-111497)
- curl: CURLOPT_ACCEPT_ENCODING(旧名 CURLOPT_ENCODING)
- Requests: Quickstart(Binary Response Content)
WEBサイト