何が起きたのか
10月21日、PHPプロジェクトは2件の脆弱性CVE-2026-109618とCVE-2026-109619の修正をリリースしました。Arctic Wolfの解説によると、どちらもCVSS 9.2と評価されており、PHPでWebリクエストを処理しているサーバー上で、認証されていない攻撃者がコードを実行できる可能性があります。
これらのバグはフレームワークやプラグインではなく、PHP自身のリクエスト処理のライフサイクルに存在します:
- CVE-2026-109618は、リクエストデータの準備が途中の段階でメモリ不足が発生してPHPが中断されたときに起きるメモリ破損です。
- CVE-2026-109619はuse-after-freeです。あるリクエストに属する状態が残り続け、同じワーカー上の後続のリクエストから読み取られる可能性があり、メモリの内容が漏えいすることもあります。
2つ目の点は立ち止まって考える価値があります。Qualysによると、漏えいしたワーカーのメモリにはパスワード、トークン、APIキーが含まれている可能性があります。つまり、誰もあなたのサーバーでシェルを取らなかったとしても、シークレットが外に持ち出されるおそれがあるのです。
パッチ公開後、事態は急速に進み、規模も大きなものです。The Hacker NewsはCensysの推計として、影響を受けるバージョンで動いているPHPサービスが今も3,200万以上あると伝えています。
- BleepingComputerの報道によると、Amazonの脅威インテリジェンスチームは、修正が公開される4日前から標的型の攻撃が始まっていたと述べています。
- 10月24日、Perplexityの研究者がハニーポットに対するコード実行の成功を確認しました(The Hacker News)。
- 10月26日、CISAは両方のCVEを既知の悪用された脆弱性(KEV)カタログに追加し、米国連邦機関に10月29日までの修正を求めました。
小さなアプリにも関係がある理由
この攻撃では、攻撃者は会社の規模で標的を選びません。インターネット全体をスキャンしてPHPらしく応答するものを探し、エクスプロイトを試します。VPS上の忘れられたサイドプロジェクトも、大規模なECサイトと同じように攻撃者から届く場所にあります。
今回の件で特に対応すべき理由がいくつかあります:
- あなたのコードには依存しません。Arctic Wolfが指摘するように、欠陥がPHPのリクエスト処理にあるため、影響はどのアプリケーションを動かしているかに左右されません。完璧に書かれたLaravelアプリでも、古いPHPビルド上で動いていれば影響を受けます。
- 多くのサーバー構成が対象です。mod_phpを使ったApacheが最もリスクが高いとされていますが、PHP-FPM、php-cgi、FrankenPHP、LiteSpeedもすべて影響を受けるとされており、PHPを同梱する製品やアプライアンスも同様です。
- 古いPHPはよく使われています。Qualysによると、バージョンを特定できたPHPインストールの約71%がすでにサポート終了(EOL)でした。8.1以前を使っている場合、通常のアップストリームの修正はありません。
アプリを確認する方法
知りたいのはサーバーごとに1つの答えです。PHPでWebリクエストを処理しているものがあるか、そしてその正確なバージョンは何か。
1. 運用しているものをすべて洗い出す。メインのアプリだけではありません。マーケティングサイト、ブログ、ドキュメント、ステージング環境、管理ツール、サブドメイン上のあらゆるものを含めてください。忘れられているものこそ危険です。
2. レスポンスヘッダーを確認する。多くのPHP環境はX-Powered-ByやServerヘッダーで自らを名乗っています。ヘッダーがないからといってPHPがないとは限りません(expose_php = Offで無効にできます)が、ヘッダーがあればすぐに「はい」とわかります。詳細なエラーページも手がかりになります。本番環境のPHPスタックトレースは、何を動かしているかを攻撃者に正確に教えてしまいます。
curl -sI https://your-site.example | grep -i -E 'x-powered-by|server'
# X-Powered-By: PHP/8.3.20 <- PHP, and an old patch level詳細なエラーページとスタックトレース:無効にする方法3. CLIだけでなく、Webトラフィックを処理しているバージョンを確認する。サーバー上のphp -vは、ApacheやPHP-FPMが実際に使っているものとは別のビルドを報告することがあります。Qualysもこの点を特に指摘しています。FPMのバイナリやWebサーバーのPHPモジュールを確認するか、ホスティング事業者に問い合わせてください。
php-fpm8.3 -v # or php-fpm -v, depending on your distro
apache2ctl -M | grep php # is mod_php loaded?4. 修正済みバージョンと比較する。LinuxディストリビューションからPHPをインストールしている場合、修正は古く見えるバージョン番号のパッケージにバックポートされていることがあるため、バージョン文字列だけでなくディストリビューションのアドバイザリを確認してください。それ以外の場合は、少なくとも次のバージョンが必要です:
- PHP 8.5:8.5.12
- PHP 8.4:8.4.27
- PHP 8.3:8.3.36
- PHP 8.2:8.2.35
5. マネージドホスティングの場合は?マネージドWordPressホストやPaaSを使っているなら、ステータスページや変更履歴でPHP2Shellに関するお知らせを確認してください。ほとんどの事業者はパッチを当ててくれますが、「ほとんど」は「すべて」ではありません。また、自分で管理しているVPSは完全にあなたの責任です。
修正する方法
パッチを当ててから再起動します。PHPの更新が唯一の完全な修正です。
再起動は重要です。実行中のワーカーは置き換えられるまで古いコードをメモリに保持し続けます。Dockerの場合は、更新されたベースイメージ(例えば最新のphp:8.3-fpmタグ)で再ビルドして再デプロイしてください。古いコンテナを再起動するだけでは不十分です。
PHP-FPM構成のDebianやUbuntuでは、通常は次のようになります:
sudo apt update && sudo apt install --only-upgrade 'php8.3*'
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2 # if you use mod_php今日パッチを当てられない場合のために、QualysがPHPの暫定的な緩和策をまとめています。リスクは下がりますが、パッチ未適用のサーバーが安全になるわけではありません。php.iniまたはFPMプール設定(.user.iniやini_setではなく)で設定し、すべてのワーカーを再起動してください。
パッチ未適用のサービスが公開されている必要がないなら、VPNやIP許可リストの背後に置くか、更新できるまでオフラインにしてください。
; php.ini or FPM pool config (not .user.ini or ini_set)
session.upload_progress.enabled = 0
post_max_size = 8M ; 32M if you need uploads
upload_max_filesize = 6M ; keep below post_max_sizePHP 8.1以前を使っているなら、今すぐアップグレードを計画してください。一部の古いブランチには限定的なバックポートがありますが、今回のようなことが起きるたびに運に頼ることになります。
侵害の兆候を探してください。予期しないプロセス、Webルート内の新しいファイル、見慣れないcronジョブ、Webサーバーからの外向き通信を確認しましょう。Arctic Wolfは、ログに残る「PHP2Shell」リクエストの多くが古い手法を再利用しているとも指摘しています。恐ろしげなログ行があっても、侵入が成功したとは限りません。
影響を受けていた場合はシークレットをローテーションしてください。CVE-2026-109619はワーカーのメモリを漏えいさせる可能性があるため、パッチ未適用でインターネットに公開されたPHPプロセスを通過したシークレットは、見られた可能性があるものとして扱ってください。データベースのパスワード、APIキー、セッション署名キー、決済プロバイダーのキーなどです。Laravelや同様のフレームワークはこれらを.envに保存するため、そのファイルがそもそもWebからアクセス可能になっていなかったかも確認してください。
クイックチェックリスト
所有しているすべてのドメインについて確認してください:
- 古いマーケティングサイトやステージングサイトも含め、所有するすべてのドメインとサブドメインを洗い出した。
- どれがPHPで動いているか、そしてWebを処理している正確なバージョンを把握している。
- それぞれが8.5.12、8.4.27、8.3.36、8.2.35、またはベンダーによるパッチ適用済みビルドになっている。
- 更新後にPHPワーカーとWebサーバーを再起動した。
- パッチ未適用のものはアクセス制限またはオフラインにし、緩和策を適用した。
- 影響を受けたホスト上のシークレットをローテーションした。
- 本番環境がPHPのバージョンを公開したり、スタックトレースを表示したりしなくなった。
より大きな教訓
PHP2Shellは数週間のうちにパッチが当てられ、忘れられるでしょう。しかしこのパターンは変わりません。「修正公開」から「悪用」までの時間は今や数日で、時にはマイナスです。小さなチームが根性で追いつくことはできません。有効なのは、自分が何を動かしているかを把握し、それに変化があったときにすぐ気づくことです。
これは、AIで作ったアプリのためのリリース前チェックリストと同じ考え方です。現実のインシデントの多くは、実際に確認しさえすれば簡単にわかることから生まれています。
AppSafeは、攻撃者が見るのと同じように、稼働中のサイトを外部からスキャンします。セキュリティヘッダーの不足、スタックを漏らすX-Powered-Byヘッダー、公開されたファイル、詳細なエラーなどの問題を探し、わかりやすい言葉で修正方法を示します。パッチを当てたら、各ドメインで無料スキャンを実行して、ついでに他の簡単な改善点も見つけましょう。
