PHP2Shellへの対応:修正済みPHPビルドとWebワーカーを検証する
この記事の目次
PHP2Shellへの対処は、CMSやプラグインの更新だけでは完了しません。CVE-2026-109618とCVE-2026-109619を修正したPHPビルドを入手し、Webリクエストを処理するすべてのワーカーがそれを使用していることを検証します。端末のphp -vが示すのは、その端末で選択されたCLIだけです。
PHP2Shellは何に影響しますか?
この二つのCVEは、PHPエンジンのリクエスト状態とメモリの生存期間に関わります。一つ目は、メモリ不足の処理によって初期化が中断された後、クリーンアップ中に不正な状態が使用される問題です。二つ目は、リクエストのメモリ解放後も内部状態が残り、同じワーカーの後続リクエストで使用される問題です。該当する条件下では、認証なしのリモートコード実行が可能です。
PHPチームのアドバイザリでは、調査対象となるWeb提供環境として、mod_phpに加えてPHP-FPM、php-cgi、FrankenPHP、LiteSpeedを挙げています。特定のSAPIであることは、サービスを対象外にする理由にはなりません。一方、脆弱なバージョンの文字列だけでは、そのサービスに到達可能な悪用経路があるとは示せません。
どのバージョンと比較しますか?
以下は、2026年10月30日に確認した、当初の二つのCVEを修正した最初の上流ソースリリースです。インストール前に、同じ供給元の現在サポートされているリリースと追加アドバイザリを確認してください。
| PHPブランチ | 両方のCVEを修正した最初のソースリリース |
|---|---|
| 8.2 | 8.2.35 |
| 8.3 | 8.3.36 |
| 8.4 | 8.4.27 |
| 8.5 | 8.5.12 |
ディストリビューションのパッケージは、短いPHPバージョンではなく、完全なパッケージリビジョンをベンダーのアドバイザリと比較します。たとえば、Ubuntu USN-8948-1は、8.3.6-0ubuntu0.24.04.13を、php8.3-fpmのUbuntu 24.04向け修正済みパッケージとしています。この番号を上流の8.3.36と比較すると、バックポートを誤判定します。この通知は、同じバージョン文字列を表示する任意の独自ビルドの真正性を保証するものではありません。
PHP 8.1以前は、PHPプロジェクトのサポートが終了しています。ベンダーのサポートとバックポートの根拠を確認するか、サポート対象のブランチに移行します。ソースのパッチが公開されていることと、サーバーがそのパッチを実行している証拠は別のものです。
CLIの証拠を集め、Webの証拠と混同しない
図は以下の収集コードに対応しています。Web SAPIでは情報を出力せずに終了します。CLIでは、修正状況を判定せずに実行ファイル、バージョン、設定を記録します。サービスの特定、パッチ適用、再起動は別の運用手順であり、このコードは実行しません。
PHP 8.2以降で、ドキュメントルート外の新しいディレクトリにファイルを保存します。PHP定数とini_getを使い、現在のプロセスだけを読み取ります。リクエストの送信、設定の変更、セッションの開始は行いません。phpinfo()ページを公開する必要はありません。
runtime-evidence.php
<?php
if (PHP_SAPI !== 'cli') {
http_response_code(404);
exit;
}
$evidence = [
'scope' => 'this-cli-process-only',
'pid' => getmypid(),
'version' => PHP_VERSION,
'sapi' => PHP_SAPI,
'binary' => PHP_BINARY,
'loadedIni' => php_ini_loaded_file() ?: null,
'uploadProgress' => ini_get('session.upload_progress.enabled'),
'serializeHandler' => ini_get('session.serialize_handler'),
];
echo json_encode($evidence, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
php runtime-evidence.php
php -n -d session.upload_progress.enabled=0 runtime-evidence.php
最初のコマンドは、選択されたCLIの設定を読み取ります。二つ目はiniファイルを読み込まず、そのCLI呼び出しだけでアップロード進捗を無効にします。Webサーバーの設定は変更せず、Webワーカーの有効な設定も確認しません。
ローカルでの確認は分離したPHP CLIコンテナで実施され、sapiがcliのJSON出力を確認しました。二つ目のコマンドでは、nullがloadedIniに、文字列"0"がuploadProgressに返りました。パス、PID、バージョン、既定値は環境によって異なります。この結果は、本番サービスの修正状況を確定するものでも、悪用を再現するものでもありません。
インストールと稼働中のワーカーを個別に検証する
- Webサーバーのupstream、FastCGI、モジュールの設定をたどり、実際のPHP実行ファイル、プール、コンテナ、レプリカを特定します。ホストのCLIとWebランタイムが同じインストール先を共有すると仮定しないでください。
- そのランタイムの供給元と完全なパッケージリビジョン、またはイメージダイジェストをアドバイザリと比較します。独自ビルドでは、修正コミットとデプロイ済み成果物の対応関係を確認します。
- 互換性のある修正済みビルドをデプロイし、影響を受けるプールやサービスのワーカー、またはコンテナを置き換えます。他のサービスがランタイムを共有している場合は、先に変更範囲を確認します。
- すべての対象で、新しいプロセスと修正済みビルドの対応関係を検証します。通常のページ、ログインとセッションの動作、アップロード、エラー率を確認します。一部だけの展開や稼働プロセスの証拠不足を、完了とみなさないでください。
内部の資産記録で「修正済み成果物を特定済み」と「稼働中の適用を検証済み」を分けると、漏れたワーカーを見つけやすくなります。クラッシュだけでは侵害を証明できず、エラーログがないことも侵害を否定する根拠にはなりません。侵害が疑われる場合は、証拠を保全し、パッチ適用とは別に調査します。
セッションの追加問題とWindows再ビルドを分ける
10月23日のPHP追加通知は、CVE-2026-115560を別に追跡しています。対象は、session.serialize_handlerがphp_binaryまたはphp_serializeに設定され、アプリケーションコードがそれをphpへ変更してからsession_start()を呼び、アップロード進捗が有効なままという組み合わせです。通知では、次の定期修正までsession.upload_progress.enabled=0を設定するよう提案しています。この設定は、当初の両CVEが完全に解決した証拠にはなりません。Web SAPIの有効な設定と機能への影響を確認してください。
10月26日のWindows通知では、パッケージ8.5.12-1、8.4.27-1、8.3.36-1、8.2.35-1を公開しています。これらには、CVE-2026-111497のBrotli修正が組み込まれています。これらはPHPソースのバージョンを変えずに依存関係を再ビルドしているため、PHP_VERSIONだけでは区別できません。cURLの応答自動展開を使用するWindows環境では、このパッケージ修正も確認する必要があります。Node.jsの同じBrotli CVEについては、Node2Shell対応ガイドを参照してください。
コメント