はじめに
対象読者: 自分が運用している PHP の環境(Docker、Debian・Ubuntu のパッケージ、共用サーバーなど)が php2shell の修正済みバージョンかどうかを確かめたい開発者・運用担当者です。
php2shell は、PHP 本体の脆弱性 CVE-2026-109618 と CVE-2026-109619 の通称です。php -v を実行して PHP 8.3.6 と出たとき、それが修正前なのか、ディストリビューションが修正を取り込んだ版なのかは、画面を見ただけでは決まりません。本記事は、環境の種類ごとに「どのコマンドで何を見れば判断材料になるか」を、筆者が実際に実行した出力とあわせて整理します。
状況の記述は 2026-10-23 JST 時点 です。復旧状況や悪用の観測は日々変わるため、最新の情報は PHP Foundation の公式ブログと、利用している配布元のセキュリティ情報で確認してください。
筆者がこのセッションで実行したのは、Ubuntu 24.04 のコンテナ上での Docker 公式イメージの比較、Ubuntu パッケージの changelog の確認、ソースの差分統計です。それ以外の環境(rpm 系ディストリビューション、Apache、PHP-FPM の本番構成)は実行していません。実行していない項目には、その旨を書きます。攻撃の再現は行っておらず、本記事にも載せません。
先に結論
修正済みの PHP バージョンは、PHP Foundation と CISA の発表では次のとおりです。
| 系統 | 修正済みバージョン |
|---|---|
| 8.5 | 8.5.12 以上 |
| 8.4 | 8.4.27 以上 |
| 8.3 | 8.3.36 以上 |
| 8.2 | 8.2.35 以上 |
出典: PHP Foundation の声明、CISA のアラート、GitHub のアドバイザリ GHSA-w8hw-w9fx-j79w
この表の見方は環境によって変わります。
-
公式 Docker イメージ:
php -vのバージョンがそのまま表と対応します。 -
Debian・Ubuntu などのパッケージ: バージョン表示は
8.3.6のままでも、パッケージのリビジョン(-0ubuntu0.24.04.13など)と changelog の CVE 記載で判断します。 - 8.1 以下: 公式の修正版リリースはありません。CISA は、すぐに更新できない組織や 8.1 以前のサポート外バージョンを使い続ける組織について、パッチ適用か更新までシステムをオフラインにすることを勧めています。
「該当しない」と断言できる確認方法は、本記事にもありません。確認できなかった場合は、更新の対象として扱うのが安全側です。
状況の整理
要点だけ、時刻は JST です。
- CVE-2026-109618 と CVE-2026-109619 の CVSS v4.0 の基本値は 9.2 です。事前に出回った 10.0 という値は誤りだったと、PHP Foundation は述べています。出典: Foundation の声明、Sansec
- 修正版 8.5.12、8.4.27、8.3.36、8.2.35 は、2026-10-21 23:00(14:00 UTC)に公開されました。当初の予定は 10-22 14:00 UTC で、1 日前倒しされています。出典: Foundation の声明
- Calif は、認証なしのリモートコード実行を確認したと説明しています。出典: Calif
- 悪用の有無は情報源によって記述が異なります。CISA はアラートの公開時点で悪用を観測していないとしており、本記事では断定しません。
PHP のバージョンを php -v で見る前に、まず「自分の PHP がどこから来たか」を切り分けます。
公式 Docker イメージを確認する
筆者の環境(Docker 29.9.1、linux/amd64)で、修正前の php:8.3.35-cli と修正後の php:8.3.36-cli を比べました。
docker run --rm php:8.3.35-cli php -v
docker run --rm php:8.3.36-cli php -v
PHP 8.3.35 (cli) (built: Oct 21 2026 00:32:41) (NTS)
Zend Engine v4.3.35, Copyright (c) Zend Technologies
PHP 8.3.36 (cli) (built: Oct 21 2026 15:57:19) (NTS)
Zend Engine v4.3.36, Copyright (c) Zend Technologies
イメージの識別子と作成時刻は次のとおりです。
docker image inspect php:8.3.35-cli php:8.3.36-cli --format '{{index .RepoDigests 0}} {{.Created}}'
php@sha256:b62d1f1ff98037e7ec8ee5e5ed382bfe2d88d054b05e0d09bcc851e3342072c2 2026-10-21T00:33:37.067293872Z
php@sha256:74caa458ad8d6c5e401eb9f8841a62faeab9b7be42b54cd37986d7685f857618 2026-10-21T15:58:08.998160558Z
ダイジェストは Docker のバージョンやストレージの方式で表示が変わりうるため、他の環境の値との照合には使わず、php -v のバージョンで判断します。2026-10-23 10:30 JST 時点で、ムーバブルなタグ php:8.3-cli を pull すると PHP 8.3.36 でした。
稼働中のコンテナは pull しても置き換わらない
見落としやすいのは、docker pull でタグが新しくなっても、すでに動いているコンテナは古いイメージのまま動き続ける点です。筆者は同じ状況を、ローカルのタグの付け替えで再現しました。
docker tag php:8.3.35-cli demo-php:cli
docker run -d --name demo demo-php:cli sleep 120
docker tag php:8.3.36-cli demo-php:cli # pull でタグが動いた状態に相当する操作
docker run --rm demo-php:cli php -v | head -1
docker exec demo php -v | head -1
PHP 8.3.36 (cli) (built: Oct 21 2026 15:57:19) (NTS)
PHP 8.3.35 (cli) (built: Oct 21 2026 00:32:41) (NTS)
1 行目がタグから新しく起動したコンテナ、2 行目が稼働中のコンテナです。
稼働中コンテナが使っているイメージとタグの現在地は、次の 2 つの値を比べると分かります。
docker inspect <コンテナ名> --format '{{.Image}}'
docker image inspect <イメージ名:タグ> --format '{{.Id}}'
筆者の実行では、前者が sha256:b62d1f1f…(8.3.35)、後者が sha256:74caa458…(8.3.36)で、値が食い違っていました。食い違うなら、コンテナを作り直す(Compose なら up -d で再作成、オーケストレーターならロールアウト)までが更新です。
Debian・Ubuntu のパッケージを確認する
パッケージ版の PHP は、上流の修正を取り込んでもバージョン表示を変えません。筆者のコンテナ(Ubuntu 24.04)のホスト側 PHP は次の状態でした。
php -v | head -1
dpkg -l | grep -E '^ii +php8.3-common' | awk '{print $2,$3}'
PHP 8.3.6 (cli) (built: Oct 7 2026 18:06:38) (NTS)
php8.3-common 8.3.6-0ubuntu0.24.04.12
PHP 8.3.36 でなくても、これだけでは未修正とも修正済みとも言えません。判断材料になるのは、パッケージの changelog に CVE 番号があるかどうかです。
zgrep -c CVE-2026-109618 /usr/share/doc/php8.3-common/changelog.Debian.gz
zgrep -c CVE-2026-109619 /usr/share/doc/php8.3-common/changelog.Debian.gz
0
0
インストール済みの .12 には、どちらの CVE 番号も記載がありませんでした。ただし、0 は「記載がない」ことを示すだけで、別の経路で修正済みでないことの証明にはなりません。
そこで、更新候補を確認し、パッケージを取得して(インストールはしません)changelog を見ました。
apt-cache policy php8.3-common | head -3
apt-get download php8.3-common=8.3.6-0ubuntu0.24.04.13
dpkg-deb -x php8.3-common_8.3.6-0ubuntu0.24.04.13_amd64.deb x
zgrep -c CVE-2026-109618 x/usr/share/doc/php8.3-common/changelog.Debian.gz
php8.3-common:
Installed: 8.3.6-0ubuntu0.24.04.12
Candidate: 8.3.6-0ubuntu0.24.04.13
2
.13 の changelog の先頭には「SECURITY UPDATE: Remote RCE via state corruption issue」の項目があり、CVE-2026-109618 は 2 行、CVE-2026-109619 は 1 行ヒットしました。この環境では、.12 の changelog に記載がなく、.13 で追加されています。
配布元のセキュリティトラッカーも、2026-10-23 JST 時点では次の表示でした(トラッカーの記述を転記したもので、筆者が各ディストリビューションで更新を実行したわけではありません)。
| ディストリビューション | パッケージ | 修正済みと表示されたバージョン |
|---|---|---|
| Ubuntu 24.04 LTS | php8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 LTS | php8.1 | 8.1.2-1ubuntu2.28 |
| Debian 12 (bookworm) | php8.2 | 8.2.35-1~deb12u1 |
| Debian 13 (trixie) | php8.4 | 8.4.27-1~deb13u1 |
出典: Ubuntu Security、Debian Security Tracker
更新の実行(apt-get install --only-upgrade など)と、PHP を読み込んでいるプロセス(PHP-FPM、Apache)の再起動は、筆者はこのセッションで行っていません。更新後に古いプロセスが残ると、旧バージョンの PHP が動き続ける可能性がある点は、Docker の場合と同じ考え方です。
rpm 系の環境では rpm -q --changelog php | grep CVE-2026-109618 のような確認が考えられますが、筆者は rpm 系環境を持っていないため実行していません。
SAPI と設定値の見方
PHP は、実行形態(SAPI)によって読み込む設定ファイルが違います。php -i で出る値は CLI の値で、PHP-FPM や Apache から動く本番の PHP とは別物の可能性があります。
公式イメージの CLI で、設定値を確認した結果です(どちらのバージョンも同じでした)。
docker run --rm php:8.3.36-cli php -i | grep -E '^(Server API|memory_limit|post_max_size|session.upload_progress.enabled) '
Server API => Command Line Interface
memory_limit => 128M => 128M
post_max_size => 8M => 8M
session.upload_progress.enabled => On => On
これは「公式イメージの CLI の既定値」であって、本番の値ではありません。本番の値は、本番の SAPI が読む設定(php.ini、conf.d、FPM のプール設定、Apache の設定)で確認する必要があります。PHP-FPM のバージョンは php-fpm -v で確認できますが、筆者はこの環境では実行していません。
緩和策の限界
更新できない間の暫定策として、公開されている資料にはいくつかの設定変更が出ています。ただし、どの資料も「パッチの代わりにはならない」と書いています。
- Calif: 「These changes do not replace a patch.」
- Sansec: 「These steps are temporary and partial. They buy time until you update PHP.」
Calif は PHP-FPM と mod_php の別に、session.upload_progress.enabled の無効化や memory_limit=-1 の設定を挙げています。一方 Sansec は、memory_limit = -1 では 1 つのリクエストがサーバーのメモリをすべて使えるため、メモリ使用量の監視と、パッチ適用後の設定の復元を勧めています。出典: Calif、Sansec
本記事は、これらの設定を推奨しません。効果と副作用は構成ごとに異なり、筆者は検証していないためです。更新が先に取れる環境では、更新を優先してください。
8.1 以下と共用サーバー
8.1 以下
PHP 8.1 以前には、公式の修正版リリースがありません。Sansec は、8.1 以前の修正は配布元(パッケージの提供者)と PHP のセキュリティチームから出ると書いています。Ubuntu 22.04 LTS の php8.1 のように、配布元がバックポートした修正を出している例が、前の表のとおりあります。サポート外の PHP を使い続けている場合は、配布元の情報を確認するか、サポート中の系統へ移行する計画が要ります。CISA の上記の勧告は、その計画が整うまでの扱いとして読めます。
共用サーバーやマネージドサービス
PHP を自分で更新できない場合は、事業者に次の 3 点を問い合わせます。
- 自分の契約環境の PHP バージョン(とパッケージのリビジョン)は何か
- CVE-2026-109618 と CVE-2026-109619 への対応は済んでいるか、済んでいないなら予定はいつか
- 対応のために利用側で必要な作業(バージョン切り替え、再デプロイなど)はあるか
契約先の告知やステータスページに対応状況が出ていないかも、あわせて確認してください。
なぜ情報が混乱したか
2026-10-21 の出来事について、各当事者の公表内容を並べます。PHP Foundation の声明は、Chainguard が 07:41 UTC(16:41 JST)、協調リリースの 6 時間以上前に "Chainguard unilaterally broke the embargo and published built images containing the fix." と述べています。同声明は、Calif が動画を誤って公開したことと、CVE 番号が誤った CVSS 10.0 とともに事前に出回ったことも挙げています。Chainguard 側は、悪用が確認されたため早く出す判断をし、判断後に関係者へ通知したと説明しています(Hacker News のコメントと Socket の記事による)。悪用の根拠は公開されていません。Foundation は、公開時点で動作する公開エクスプロイトを確認できなかったとしています。誰の判断が妥当だったかは、本記事では判断しません。出典: Foundation の声明、Socket
なぜ一行の修正では済まなかったのか
修正版が公開された 8.3.36 は、NEWS に次の 1 項目だけが載っています。
22 Oct 2026, PHP 8.3.36
- Core:
. Fixed GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp (Avoid state corruption via
bailout). (CVE-2026-109618, CVE-2026-109619) (Arnaud, ilutov, Jakub Zelenka,
ndossche, Nicolas Grekas)
NEWS の日付は 22 Oct 2026 で、当初予定のリリース日が残っています。php.net のリリース JSON では、8.3.36 の公開日は 21 Oct 2026 でした。
筆者は、公式イメージに同梱された /usr/src/php.tar.xz から 8.3.35 と 8.3.36 のソースを取り出し、差分の規模を数えました。
docker run --rm php:8.3.35-cli cat /usr/src/php.tar.xz > s35/php.tar.xz # 8.3.36 も同様
diff -rq -x '*.phpt' s35/php-8.3.35 s36/php-8.3.36 | grep -c '^Files'
find s36 -name 'oom_*.phpt' | wc -l
| 項目 | 計測値 |
|---|---|
| テスト(.phpt)を除いた、内容が変わったファイル数 | 140(ほかに新規ファイル 10) |
| 同、追加・削除された行数(生成物を含み、新規ファイルを除く) | +12,155 / -10,880 |
同、生成物(zend_vm_execute.h、parse_date.c、.re、configure など)を除いた行数 |
+5,524 / -2,168 |
Zend/zend_hash.c の行数 |
+259 / -43 |
8.3.36 で新たに追加された oom_*.phpt
|
220(8.3.35 は 0) |
内容が変わった 140 ファイルを上位ディレクトリ別に見ると、ext が 84、Zend が 31、main が 10 でした。バージョン番号の更新やビルドファイルの変更も含まれるため、修正だけの正味の量ではありません。
NEWS が 1 項目であるのに対し、差分は Zend エンジンと多数の拡張に及んでいます。筆者の所見は、「特定の 1 関数を直した」というより、処理を途中で打ち切る場面の扱い全般を見直した規模の変更に見える、というものです。この規模は、更新を待たずに自分でパッチを当てる方法が現実的でない理由の 1 つです。公式のパッケージ更新を使うのが堅実です。
確認できなかったこと
- rpm 系ディストリビューション、Apache、PHP-FPM の本番構成での確認は、筆者は実行していません。
- CVE 番号の流出元、悪用の実態、影響する最古のバージョンは、情報源によって記述が異なります。Sansec は 5.4 以降の経路を指摘しています。
- トラッカーの表示は 2026-10-23 JST 時点のものです。パッケージの更新状況は変わるため、実行前に最新の表示を確認してください。
更新履歴
- 2026-10-23 JST: 初版を公開しました。
参考リンク
- PHP Foundation: Today's PHP security release and how we're strengthening PHP security
- CISA: Critical Vulnerabilities in PHP Require Immediate Patching
- GitHub Security Advisory GHSA-w8hw-w9fx-j79w
- Calif: php2shell
- Sansec: php2shell
- Socket: PHP embargo dispute
- php.net リリース JSON(8.3)
- Ubuntu Security: CVE-2026-109618
- Debian Security Tracker: CVE-2026-109618