FrankenPHPにBrotli脆弱性、修正版1.13.2あり
FrankenPHPの静的バイナリに同梱されたBrotliに脆弱性があり、外部から届くデータを解凍するアプリは、プロセスごと落とされるおそれがあります。修正版に更新し、brotli_uncompress_add()の使用箇所を洗い出してください。
急ぎ度: 早めに
CVSS v3は8.1、v4は9.2で、認証なしにネットワーク越しで届く脆弱性ですが、悪用には特定の関数に外部データを渡すアプリであることが要り、修正版も出ています。
関係があるか
FrankenPHPの静的バイナリ(単体で動く配布物)で、PHPアプリがアップロードやリクエストボディなどの外部データをBrotliで解凍している環境です。Dockerイメージ版とWindows版は、curl拡張が使うBrotliの更新も別の版で出ています。
| 製品 | 影響を受ける版 | 修正版 |
|---|---|---|
| FrankenPHP 静的バイナリ | 1.8.0以上、1.13.2未満(1.13.1まで) | 1.13.2(Brotli 1.2.1を同梱) |
| FrankenPHP Dockerイメージ | brotli拡張は既定で読み込まれない。PHPのcurl拡張がシステムのBrotliでレスポンスを解凍する(勧告が対象とする版の範囲は静的バイナリ) | 1.13.4以降(Debian TrixieとAlpineはディストリビューションのセキュリティ更新、Debian BookwormはBrotli 1.2.1をソースからビルド) |
| FrankenPHP Windows版 | curl拡張が使うbrotlidec.dllが対象(勧告が対象とする版の範囲は静的バイナリ) | 1.13.4以降(Brotli 1.2.1、PHP 8.5.12-1のWindowsビルド) |
確かめ方
- 1FrankenPHPをどの形で配備しているか(静的バイナリ、Dockerイメージ、Windows版)を洗い出し、
frankenphp versionで版を確認します。 - 2静的バイナリで1.8.0〜1.13.1に当てはまる場合は、アプリのソースコードでbrotli_uncompress_add() とbrotli_uncompress() の呼び出しを検索し、外部のデータが渡っていないかを確認します。
- 3DockerイメージとWindows版では、PHPのcurl拡張でCURLOPT_ENCODINGを使って外部のBrotli応答を受けていないかを確認し、版が1.13.4より前なら更新の対象にします。
何が起きたか
FrankenPHPの静的バイナリに同梱されたBrotliのデコーダーに脆弱性があり、悪用されるとFrankenPHPのプロセス全体が停止します。メモリ内容の漏えいやコード実行につながる可能性もあります。
原因はBrotli 1.2.0のデコーダーにある境界外書き込み(CVE-2026-111497、CWE-787)です。1.8.0から1.13.1までの静的バイナリは、PHPのbrotli拡張をこのBrotliに静的リンクして同梱していました。GitHubの勧告は、戻り値を確認しない問題(CWE-252)も挙げています。
勧告によると、報告者は公式の1.13.1のLinux x86-64バイナリで、プロセスがSIGSEGVで終了することを確認しています。同じ入力を1.13.2に与えても、エラーとして拒否されるだけでプロセスは動き続けます。
攻撃の流れ
-
1
入力経路の特定
brotli_uncompress_add() に外部のデータを渡しているアプリを、攻撃者が探します。
-
2
細工データの送信
認証なしで、ネットワーク越しに細工したデータを1回送ります。
-
3
解凍で範囲外書き込み
同梱のBrotli 1.2.0のデコーダーが、確保した領域の外にデータを書き込みます。
-
4
プロセス停止
FrankenPHP全体が落ち、同じプロセスで動くサイトがすべて止まります。
どう悪用されるか
認証は要りません。ネットワーク越しに届き、利用者の操作も要りません。CVSSの攻撃条件の複雑さは高と評価されています。
ただし、アプリが外部の入力をbrotli_uncompress_add() に渡していることが前提です。アップロード、リクエストボディ、キューのメッセージ、取得したコンテンツの段階的な解凍が、その例として挙げられています。brotli拡張を読み込んでいるだけでは悪用できません。Caddyのbr応答エンコードはエンコーダーしか使わないので、影響を受けません。
条件がそろうと、1回のリクエストでFrankenPHPのプロセス全体が落ち、サービスが止まります。メモリの漏えいやコード実行の可能性も指摘されています。
今すぐやること
-
1
使っている版と配備の形を確認する
静的バイナリの版を調べ、1.8.0〜1.13.1に当てはまるかを見ます。Dockerイメージ版とWindows版も、版が1.13.4より前かどうかを確認します。
frankenphp version -
2
外部データを解凍している箇所を洗い出す
アプリのソースコードで、brotli_uncompress_add() とbrotli_uncompress() の呼び出しを検索します。アップロードやリクエストボディ、キューのメッセージ、取得したコンテンツが渡っているなら、優先して更新します。
grep -rn "brotli_uncompress" /path/to/app -
3
修正版に更新する
静的バイナリは1.13.2以降に更新します。DockerイメージとWindows版を使っている場合は、curl拡張が使うBrotliも修正された1.13.4以降を選びます。
-
4
更新後の動作とプロセスの停止履歴を確認する
更新後に、解凍処理を含む機能を一通り動かして確認します。更新前の期間に、原因の分からないプロセス停止や再起動(SIGSEGVでの終了)がないかも、運用ログで見ておきます。
すぐ更新できないとき
すぐに更新できないときは、信頼できないデータをbrotli_uncompress_add() とbrotli_uncompress() に渡さないようにアプリ側で止めます。外部から届く入力を解凍している機能は、更新まで無効にするのが確実です。
背景
FrankenPHPはCaddyの上でPHPを動かすアプリケーションサーバーで、静的バイナリなら1ファイルを置くだけで配備できます。今回の脆弱性は、FrankenPHPのコードではなく、同梱されたBrotliにあります。ライブラリを静的に取り込んでいるため、OS側のパッケージを更新しても直らず、FrankenPHP自体の更新が要ります。
BrotliはWebの圧縮形式として広く使われており、FrankenPHPのbrotli拡張はPHPコードから解凍を呼び出せるようにするものです。今回の対象は静的バイナリですが、DockerイメージとWindows版では、curl拡張がBrotliの応答を解凍する経路があります。そのため1.13.4でこちらも更新されました。
よくある質問
Q.CVE番号が2つあるのはなぜですか。
Q.深刻度がHighとcriticalで分かれているのはなぜですか。
まだ分かっていないこと
- メモリの漏えいやコード実行は、FrankenPHPに対して実証されていません。
- DockerイメージやWindows版で、curl拡張を経由して同じ脆弱性を実際に悪用できるかどうかは、勧告に書かれていません。
この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。
影響パッケージ
| パッケージ | 影響を受ける版 → 修正版 | |
|---|---|---|
| phpfrankenphp |
1.8.0 以上 1.13.2 未満→ 1.13.2 |
1.13.2 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
FrankenPHP standalone static binaries 1.8.0 before 1.13.2 bundle the PHP brotli extension statically linked with Brotli 1.2.0, whose decoder contains an out-of-bounds write (CVE-2026-111497). Unauthenticated remote attackers can send crafted data to applications that pass it to brotli_uncompress_add() to crash the entire FrankenPHP process, and possibly cause memory disclosure or code execution.
出典: CVE.org (CVE Program・cvelistV5) NVD