PHPの緊急脆弱性CVE-2026-109618の修正版が出た|確かめるのはphp -vではなく、Webで動いている方の版
PHPの緊急脆弱性2件の修正版(8.5.12・8.4.27・8.3.36・8.2.35)が出た。
ファイル添付のフォームが無いサイトも対象。
Webで動いている版の確かめ方、更新の順番、公式の暫定策を設定名つきでまとめた。
PHPの緊急脆弱性2件(CVE-2026-109618・CVE-2026-109619)の修正版が、日本時間の10月21日23時に出ました。
番号は 8.5.12・8.4.27・8.3.36・8.2.35 で、これより前の版は全て影響を受けます。
ファイル添付のフォームが無いサイトも対象なので、PHPのサーバーを触れる人は更新の段取りを始めてください。
この記事は、サーバーを自分で触る人向けに、手を動かす順番で書きます。
Webで動いている版の確かめ方、更新の順番、公式の暫定策の設定名、multipart を使わないURLの止め方です。
一般向けにまとめた版は note に書きました(末尾にリンクがあります)。
※ 2026年10月21日夜(日本時間)時点の、PHP公式の告知と GitHub の脆弱性情報2件をもとに書いています。
2件の脆弱性の中身
深刻度はどちらも CVSS v4.0 で 9.2(Critical)です。
認証なしで、外からサーバー上の任意のコードを実行される恐れがあります。
- CVE-2026-109618:メモリ不足(OOM)で処理を打ち切る時に、作りかけの内部データが残ります。後片付け(shutdown)の処理が、それを正しいデータとして扱ってしまう不具合です。multipart の解析を細工して、わざとメモリ不足を起こさせるのが入口です。
- CVE-2026-109619:リクエスト専用の内部状態が、解放された後もワーカーに残ります。同じワーカーが次のリクエストを処理する時に、初期化の前にそれを参照してしまう use-after-free です。入口は
session.upload_progress(初期設定で有効・session_start()不要)、mod_php の.htaccessのphp_valueなどが出す早い段階の設定警告、PHP 8.5 のfatal_error_backtracesです。
公式の告知で最も危険とされているのは、Apache の mod_php です。
認証なしのリクエストで、アプリのコードが動く前に攻撃が成立することが実証されています。
PHP-FPM でも、109619 の upload progress の経路で任意コード実行が確かめられています(アプリ側の条件つき)。
実際に悪用されたかどうかは、公式の情報には書かれていません。
ただ、研究者の検証は済んでいて、技術的な中身も公開されています。
僕は「まだ攻撃されていない」を、更新を待つ理由にはしないつもりです。
対象は、Webのリクエストを処理している全てのPHP
公式が挙げているのは PHP-FPM・Apache mod_php・php-cgi・FrankenPHP・LiteSpeed です。
動かし方を問わず、Webから届くリクエストを PHP が処理していれば対象です。
見落としやすいのが、アップロード機能の有無です。
multipart のリクエストは、受け取る側にフォームがあるかどうかに関係なく、PHPで動くどのURLにも送れます。
109618 の advisory も、multipart を使わないアプリはフロント(Webサーバーやプロキシ)で止めるよう書いています。
Webで動いている版の確かめ方
最初の落とし穴は php -v です。
これはコマンドライン用(CLI)のPHPの版で、Webのリクエストを処理しているPHPとは別のことがあります。
CLIだけ新しくて、Webの方は古いまま、ということは普通に起きます。
- PHP-FPM:FPM 自体の版を見ます(
php-fpm -v。配布元によってphp-fpm8.3 -vや/usr/sbin/php-fpm -vのように名前が違います)。複数の版の FPM が同居しているサーバーでは、Webサーバーの設定がどのソケットに渡しているかまで確かめます。 - mod_php:Apache に読み込まれているモジュールの版です。
apachectl -Mで PHP のモジュールが載っているかを見て、そのモジュールのパッケージの版を確かめます。 - レンタルサーバー:管理画面のPHPの版の設定と、サーバー会社のお知らせを見ます。
配布元のパッケージは、版の番号を上げずに修正だけを取り込む(バックポートする)ことがあります。
その場合は番号だけでは判断できないので、パッケージの変更履歴に CVE 番号が載っているかで確かめます(RHEL 系なら rpm -q --changelog、Debian 系なら apt changelog など)。
確認のために phpinfo() のファイルを公開領域に置くのは避けたいところです。
消し忘れると、それ自体が攻撃する側の下調べに使われます。
更新の順番
- 本番のバックアップを取る(ファイルとDB)。
- 検証用の環境で先に上げて、画面・フォーム・管理画面・定期実行が動くかを見る。
- 本番を上げる。
- PHP-FPM か Apache を再起動して、全ワーカーを入れ替える。パッケージを入れ替えただけでは、動いているワーカーが古いまま残ることがあります。
- Webで動いている版(または変更履歴の CVE 番号)を、もう一度確かめる。
Linux の配布元と LTS のベンダーには、修正が事前に渡されています。
公式も、配布元の更新パッケージを確認するよう案内しています。
remi から入れている場合と、8.1 以前の場合
有志が運営している remi リポジトリ(rpms.remirepo.net)は、公式の告知に「当日は更新なし」と書かれていました。
配布元のパッケージへ切り替えるか、ソースからビルドするよう勧められています。
8.1 以前には、公式の更新は出ません。
7.4・8.0・8.1 向けには、最小限のソースパッチが GitHub のブランチで提供されています。
自分でビルドして当てられる人向けなので、多くの場合は 8.2 以降への移行が本命になると思います。
移行先を選ぶ時に気をつけたいのが、8.2 のサポートが 2026年12月31日で終わることです。
今 8.2 へ上げると、2か月ほどでもう一度上げることになります。
アプリが動くなら、僕は 8.3 以降を選びます。
更新までの暫定策(設定名つき)
公式は「完全な回避策は無い。更新だけが安全」と書いています。
暫定策は、確かめられた攻撃の道筋を減らすだけです。
更新の日までのつなぎとして使います。
session.upload_progress.enabled=0:php.ini、FPM のプール設定、Webサーバーの設定のどれかに書き、全ワーカーを再起動します。ini_set()と.user.iniでは効きません。ini_set()はスクリプトが動き始めてからの設定なので、リクエストの本文を読む段階には間に合いません。.user.iniも公式が効かないと明記しているので、ワーカーが起動する時に読む設定で切る、と覚えておくのが安全だと思います。post_max_size:アップロードが不要なら 8M、必要なら 32M。upload_max_filesizeはpost_max_sizeより小さくします。memory_limit=-1:php_admin_value(FPM のプール設定や Apache の設定)で固定し、下位の設定で戻されないかを確かめます。上限が無くなるぶん、cgroup などワーカー単位のメモリ制限と組み合わせます。PHP 自身がメモリ不足で処理を打ち切る経路(109618)を通らせないための設定だと、僕は読んでいます。fatal_error_backtraces=0(PHP 8.5 のみ):入れたら全ワーカーを再起動します。- リクエストのたびに警告が出る設定を消す:不正な値や非推奨の設定は、初期化の前に警告を出し、109619 の入口になります。
error_reporting・display_errors・@では防げません。mod_php なら.htaccessのphp_valueも見直します。
multipart を使わないURLは、Webサーバーで止める
アップロードを受け付けるURLは、サイトの中でも限られています。
それ以外のURLに届く multipart の POST は、PHP に渡す前に Web サーバーで断ってしまう、というのが考え方です。
- アップロードを受け付けるURL(管理画面のメディア登録、添付つきの問い合わせなど)を洗い出す。
- それ以外のパスで、
Content-Typeがmultipart/form-dataのリクエストを 403 などで返す。 - 残したアップロードの入口が、ログイン必須になっているかを確かめる。
書き方の一例です。
アップロードを受け付けるパスには当てないよう、環境に合わせて範囲を絞ってください。
# nginx(アップロードを受け付けない location の中)
if ($http_content_type ~* "^multipart/form-data") { return 403; }
# Apache(mod_rewrite。/upload/ はアップロードを受け付けるパスの例)
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/upload/
RewriteCond %{HTTP:Content-Type} ^multipart/form-data [NC]
RewriteRule ^ - [F]入れたら、アップロードのあるページで実際にファイルが送れることを確かめます。
止めすぎて管理画面の画像登録が動かなくなるのが、いちばんありそうな失敗です。
公式は、リクエストの大きさ・入力項目の数・multipart の part の数・ヘッダーの数・入れ子の深さを、Webサーバーやプロキシで制限することも勧めています。
Content-Length の無いリクエストにも効くようにする、という注記つきです。
nginx なら client_max_body_size、Apache なら LimitRequestBody・LimitRequestFields あたりが入口になります。
僕が今夜やったこと
修正版の番号が出てから、僕が管理しているサーバーで次のことをしました。
- PHPの版の一覧を作り直し、どのサーバーをどこまで上げるかを1行ずつ書き足した。
- ファイルを受け取る機能が無いURLへの multipart の POST を、Webサーバーで PHP に渡る前に止めた。
- 管理用 API のファイル受け取り口を認証必須にした。アップロード先では、スクリプトを実行させない設定にした。
- 公開フォルダに残っていた PHP の控えファイルを外し、控えファイルの配信を拒否する設定を入れた。
控えのファイルは、今回の脆弱性とは別の話です。
こういう点検の時に、別の穴が見つかるのはよくあることだと思います。
公開領域に置いてはいけないものを毎週確かめている話は、露出チェックを流した回に書きました。
あとは、配布元の修正パッケージを待って更新します。
サポートが終わったOSで動いていて、通常の更新では修正版が入らないサーバーもあります。
そこは移行を前倒しにします。
やることの順番
- Webで動いているPHPの版を確かめる(
php -vだけで済ませない)。 - 8.5.12・8.4.27・8.3.36・8.2.35 より前なら、バックアップ→検証環境→本番の順で更新し、ワーカーを再起動する。
- すぐ更新できないサーバーは、暫定策を入れて全ワーカーを再起動する。
- multipart を使わないURLは、Webサーバーで止める。
- 8.1 以前は 8.2 以降(できれば 8.3 以降)への移行を決める。remi から入れている場合は、入れ方を切り替える。
一般向けに「何が起きたか・何をすればよいか」をまとめた版は、note に書きました。
PHPの緊急脆弱性の修正版が出た。ファイル添付のフォームが無いサイトも対象だった(note)
※ 調査と下書きは、AI(Claude)と一緒に行いました。一次情報の確認、内容の判断、サーバーでの作業と公開は僕が行っています。
出典
ほかにも書いています
受託・note・スタンプこういう仕組みを作る相談を受けています
毎日の更新・データ集め・集計の自動化/3万円〜収益がいくらだったか、どの施策が外れたか
note / 個人の視点で掘り下げていますスタンプラリーに挑戦する
行った場所は、現地チェックインで記録に残せます※受託の相談とnoteは、運営者が個人で受けている・書いているものです。
