PHPの重大な脆弱性「PHP2Shell」が公表されました。認証なしでサーバー上のコードを実行される可能性があり、悪用も確認されています。
PHPで動く業務システムやWordPressを管理しているなら、まず調べたいのはWebリクエストを処理しているPHPが修正済みかです。
ここで厄介なのは、PHPの更新コマンドが成功しても、古いワーカーが動き続ける場合があることです。
パッケージを更新しただけで安心せず、Web側でどのPHPが動いているか、古いワーカーが残っていないかまで確かめたいところです。 その確認を軸に、更新、再起動、侵害の初動調査まで順番に整理します。
まず30秒で対象を判断する
最初に確認するのは3点です。
- Web側で動いているPHPの系列とバージョン
- パッケージ提供元によるCVEの修正状況
- 更新後に古いPHPワーカーが残っていないか
2026年10月21日に公表された修正版は次のとおりです。
| PHP系列 | 修正版 | 確認すること・次の対応 |
|---|---|---|
| 8.5 | 8.5.12 | 未修正なら更新・再起動 |
| 8.4 | 8.4.27 | 未修正なら更新・再起動 |
| 8.3 | 8.3.36 | 未修正なら更新・再起動 |
| 8.2 | 8.2.35 | 更新後、サポート終了にも備える |
| 8.1以前 | 通常の修正版なし | 提供元の対応確認と移行計画 |
OSの提供元が修正をバックポートしている場合は、バージョン番号だけで判断できません。
Web側のPHPが不明なら次の節へ。未修正なら更新の節へ。更新できない場合は暫定策の節へ進んでください。
PHP2Shellとは
2026年10月21日、The PHP Groupは次の2件を公表しました。
| CVE | 問題 |
|---|---|
| CVE-2026-109618 | OOM時のリクエストデータ処理 |
| CVE-2026-109619 | 解放済みメモリに関係する状態の残存 |
いずれも認証なしのリモートコード実行につながる可能性があり、CVSS v4.0の深刻度は9.2です。
CVE-2026-109618は、特にApacheのmod_php構成で危険度が高くなります。
公式の詳細は、それぞれCVE-2026-109618のアドバイザリとCVE-2026-109619のアドバイザリで確認できます。
JPCERT/CCの注意喚起では、悪用を試みる通信の観測報告が相次いでいると説明されています。
米CISAも10月26日、2件を悪用が確認された脆弱性のカタログに追加しました。最新の登録状況はCISAのKEVカタログで確認してください。
Web側で動くPHPを特定する
php -vだけで判断するのは危険です。
例えば、CLIがPHP 8.4でも、Web側のPHP-FPMは8.2という構成が考えられます。
確認の順番は、Webサーバーの接続先 → 稼働プロセス → パッケージの修正状況です。
1. 実行方式を確認する
| 実行方式 | 調べる対象 |
|---|---|
| PHP-FPM | Webサーバーの接続先とFPMマスター |
| mod_php | ApacheのPHPモジュールと子プロセス |
| コンテナ | 稼働コンテナ内のPHP |
Debian系のApacheなら、読み込まれているモジュールを確認できます。
apache2ctl -M | grep -E 'php|proxy_fcgi'
ただし、モジュールの存在だけでは対象サイトの実行方式は確定しません。
ApacheのVirtualHost設定やNginxのfastcgi_passを確認し、リクエストがどこへ渡されるかを調べます。
2. FPMマスターを確認する
PHP-FPMの場合、まずプロセスを確認します。
ps -eo pid,ppid,args | grep '[p]hp-fpm'
systemd環境ではサービスも調べます。
systemctl list-units --type=service --state=running | grep -E 'php.*fpm'
サービス名がphp8.2-fpmなら、起動設定を確認します。
systemctl show php8.2-fpm -p MainPID -p ExecStart
FPMマスターのPIDが分かったら、実行ファイルを確認します。
sudo readlink /proc/1234/exe
1234は実際のPIDに置き換えてください。
readlinkは実行ファイルへのリンク先を表示します。更新前の実行ファイルが削除されている場合、末尾に(deleted)が付くことがあります。
ただし、同じパスでバイナリが置き換わった場合もあるため、パスだけでは修正済みか断定できません。
この段階で分かるのは、どのプロセスがどの実行ファイルを使用しているかです。脆弱性が解消された証明ではありません。
3. 提供元の修正状況を照合する
Debian系では次のコマンドを使います。
dpkg-query -W 'php*'
RPM系なら次の方法があります。
rpm -qa | grep -E '^php'
インストール済みパッケージを確認したら、OSやPHP提供元のセキュリティ情報で対象CVEへの対応状況を照合します。
ここまでで、Web側のPHPと修正すべきパッケージを特定できます。
更新しただけでは終わらない。PHPワーカーを入れ替える
新しいPHPをインストールしても、古いワーカーが残る可能性があります。
そのため、更新後はパッケージ、プロセス、Web側の実効バージョンを別々に確認します。
1. 関連パッケージを更新する
Debian系なら、まずインストール済みPHPパッケージを確認します。
dpkg-query -W 'php*'
PHP-FPMやCLIだけでなく、php8.2-common、拡張モジュール、Apache用モジュールなども確認対象です。
更新前には変更対象と依存関係を確認し、必要なバックアップを取得します。
Debian系の更新例です。
sudo apt update
sudo apt upgrade
apt upgradeはPHP以外の更新も対象にするため、提示される変更内容を確認してください。
リポジトリに修正版がなければ、コマンドが成功しても問題は解消しません。
2. PHPワーカーを再起動する
サービス名がphp8.2-fpmの場合です。
sudo systemctl restart php8.2-fpm
sudo systemctl status php8.2-fpm
プロセスの起動時刻を確認します。
ps -eo pid,lstart,args | grep '[p]hp-fpm'
さらに、更新後のFPMマスターについて/proc/<PID>/exeを再確認します。
ここで見るのは、古いプロセスが終了したか、修正済みパッケージの実行ファイルで起動し直されたかです。
実行方式によって確認対象は異なります。
| 実行方式 | 更新後の確認 |
|---|---|
| PHP-FPM | マスターとワーカーの入れ替え |
| mod_php | Apache再起動と古い子プロセスの終了 |
| コンテナ | 修正版イメージへの置き換え |
| 複数サーバー | 全インスタンスへの反映 |
Debian系でApacheを再起動する例です。
sudo systemctl restart apache2
サービス名は環境によって異なります。
コンテナではホスト側のPHPを更新しても意味がありません。修正版イメージを作成し、旧イメージ由来のコンテナが残っていないことを確認します。
3. Webリクエストで確認する
最後に、実際のWebリクエストを処理するPHPのバージョンと主要な業務機能を確認します。
診断用の情報をWeb経由で表示する場合は、アクセスを制限し、確認後に削除してください。
更新前後の確認をまとめると、次のようになります。
| 更新前 | 更新後 |
|---|---|
| Webサーバーの接続先 | 接続先が想定どおりか |
| FPMマスターのPID | 新しいプロセスに入れ替わったか |
| PHPパッケージ | 対象CVEの修正が適用されたか |
| Web側のPHP | 修正済みPHPが応答しているか |
| 主要な業務機能 | 更新後も正常に動くか |
更新コマンドの成功は、更新作業の一部にすぎません。
更新できない場合は、暫定策の適用可否を判断する
古い業務システムでは、フレームワークや拡張機能の互換性によって、すぐにPHPを更新できない場合があります。
ただし、公式アドバイザリは完全な対策はPHPのアップデートだけとしています。
暫定策を検討する順番は次のとおりです。
- 正式更新が可能か確認する
- 外部メモリ制限とアップロード機能への影響を確認する
- 負荷試験、監視、切り戻し手順を用意する
- 暫定策を適用して全ワーカーを再起動する
- 正式更新の期限を決める
CVE-2026-109618
CVE-2026-109618の公式アドバイザリでは、OOM処理に関する部分的な緩和策が示されています。
| 項目 | 暫定対応 |
|---|---|
| memory_limit | -1 |
| post_max_size | アップロード不要なら8M、必要なら32M |
| upload_max_filesize | post_max_sizeより小さくする |
| メモリ制御 | コンテナやcgroupで制限 |
memory_limit=-1はPHP自身のメモリ上限を解除します。
外部メモリ制限が適切でも、OOM Killerによるプロセス終了やサービス停止の可能性は残ります。
外部制限、負荷試験、監視、切り戻し手順、正式更新期限を確認できない場合は、安易に適用しないでください。
以下は設定項目を示す例であり、そのまま本番投入するためのものではありません。
memory_limit = -1
post_max_size = 32M
upload_max_filesize = 16M
公式アドバイザリでは、RLIMIT_ASとRLIMIT_DATAを使用しないよう指定されています。
この緩和策はCVE-2026-109619を解消しません。
CVE-2026-109619
CVE-2026-109619の公式アドバイザリでは、セッションのアップロード進捗機能を無効にする暫定策が示されています。
session.upload_progress.enabled = 0
php.iniやFPMプールなど、サーバー管理者が制御する設定で適用します。
ini_set()や.user.iniでは不十分です。リクエスト処理中に設定を変更しても、アップロード処理がすでに進んでいる場合があるためです。
設定後は全ワーカーを再起動し、実効値とアップロード機能への影響を確認します。
PHP 8.5では、追加の暫定策として次の設定も示されています。
fatal_error_backtraces = 0
暫定策を適用したら、メモリ使用量、エラー、ワーカーの状態を監視し、正式更新までの期限を記録します。
侵害調査は、リクエストとワーカーの時系列を突き合わせる
PHPを更新しても、過去の侵害がなかったことにはなりません。
JPCERT/CCの注意喚起では、調査の手掛かりとして次の点が示されています。
- 不自然に長い、または異常な形式の
PHPSESSIDCookie - 不審な
multipart/form-dataリクエスト前後のメモリエラーやHTTP 500 - PHPワーカーの異常終了や頻繁な再起動
ただし、レスポンスのSet-Cookieヘッダーは、通常のアクセスログには保存されていない場合があります。
まずログの保存先、ローテーション、保持期間を確認し、調査可能な期間を決めます。
そのうえで「いつ、どのリクエストで、どのワーカーに異常が起きたか」を時系列で突き合わせます。
以下は一般的なApacheアクセスログでHTTP 500を探す参考例です。
sudo grep ' 500 ' /var/log/apache2/access.log
ログ形式によってステータスコードの位置が異なるため、抽出結果の確認が必要です。
PHPのメモリエラーを探す参考例です。
sudo grep -Ei 'Allowed memory size|Out of memory' /var/log/php*-fpm.log
ログがファイルではなく、systemdのジャーナルやコンテナログに記録される場合もあります。
systemd環境なら、対象期間を指定して確認できます。
sudo journalctl -u php8.2-fpm --since "2026-10-21"
日付は例です。実際にはログの保持状況と調査方針に合わせて設定してください。
HTTP 500やメモリエラーは通常の障害でも発生します。単独では侵害の証拠になりません。
これらは初動調査です。侵害の疑いが強い場合は証拠を保全し、影響範囲の確認と適切なインシデント対応につなげます。
古いPHPは、今夜の封じ込めと移行を分ける
PHP 8.1以前には、今回の通常の修正版が提供されません。
公式アドバイザリにはPHP 7.4、8.0、8.1向けの限定的なバックポートがありますが、継続的な保守が保証されるわけではありません。
PHP 8.2も2026年12月31日にサポートが終了します。
PHPのサポート対象バージョンを確認し、必要な保守期間を確保できる系列を移行先に選びます。
古い業務システムでは、対応を3段階に分けるのが現実的です。
| 時期 | 対応 |
|---|---|
| 今夜 | 影響確認と可能な封じ込め |
| 短期 | 修正版の適用と動作検証 |
| 中期 | サポート対象PHPへの移行 |
古いコードの作り直しに関わってきた経験から、移行では最初に依存関係を整理することが重要だと考えています。
確認する順番は、PHP本体、フレームワーク、拡張モジュール、業務上停止できない機能です。
それぞれについて、更新先への対応状況と、更新を妨げている箇所を整理します。
全面的な書き直しを前提にせず、必要な改修を切り分けます。
補足:10月23日に公表された別のCVE
2026年10月23日には、CVE-2026-115560も公表されました。
これは、session.serialize_handlerがphp_binaryまたはphp_serializeで、session_start()前にini_set()でphpへ変更し、アップロード進捗機能が有効な場合に関係する問題です。
最初の2件とは影響条件が異なります。詳細はPHP公式の10月23日の発表を確認してください。
最後に残すのは、作業履歴ではなく確認結果
脆弱性対応では、何を実行したかだけでなく、どの状態を確認できたかを残します。
例えば、次の記録様式です。
| 記録項目 | 残す内容 |
|---|---|
| 対象サーバー | ホスト、コンテナ、対象アプリケーション |
| CVEへの修正状況 | PHP系列、パッケージ提供元、修正確認結果 |
| 稼働プロセス | PID、実行ファイル、再起動確認結果 |
| Web側の確認 | 実効バージョンと主要機能の動作結果 |
| 侵害の初動調査 | 対象期間、確認したログ、調査結果 |
| 未対応リスク | 暫定策、制約、残るリスク |
| 次回確認日 | 正式更新・移行・再調査の予定 |
この記録があれば、更新作業を引き継ぐ人も、何が確認済みで何が残っているかを判断できます。
更新コマンドが成功したことではなく、修正済みコードが実際に稼働していることを確認し、その証拠を残す。
そこまでを今回の対応の完了条件にします。

