2026/10/23

PHP2Shellで何が起きたのか。脆弱性の仕組みと公開までの経緯

はじめに:PHP2Shellとは

PHPはログインや予約、問い合わせフォームなど、Webサービスの裏側で使われるプログラミング言語です。

弊社スマレジでも利用していますし、WordPressやEC-CUBEなどのCMS、LaravelやSymfonyなどのフレームワークもPHPで作られています。

「PHP2Shell」はPHP本体に見つかった2つの重大な脆弱性の通称です。条件がそろうと、攻撃者がログインせずにサーバー上で不正なプログラムを実行させ、情報の漏えいや改ざんを引き起こす恐れがあります。

2026年10月21日、PHPプロジェクトはこの問題を修正したバージョンを公開しました。特定のWebサイトやプラグインに限った問題ではなく、PHPがリクエストを処理する仕組みに原因があります。

今回は脆弱性の仕組みと、修正版の公開前に攻撃情報が広まった経緯を調べました。何が起きたのかを時系列で整理し、PHPの運用で気を付けたいこともまとめます。

引用元:PHP: News Archive - 2026

PHP2Shellの仕組み

PHP2Shellとして公表された問題は、次の2つのCVEに整理されています。CVEは脆弱性を識別するための共通番号で、CVSSは深刻度を数値で評価する指標です。どちらもCVSS v4.0で9.2、深刻度は「Critical(緊急)」と評価されています。

脆弱性問題の概要
CVE-2026-109618メモリ不足で処理を中断した際、初期化途中のデータが残り、終了処理がそれを正常なデータとして扱ってしまう
CVE-2026-109619解放済みメモリへの参照が内部状態に残り、同じワーカーが後続のリクエストで使ってしまう

ここでいうメモリ不足は、サーバー全体のRAMが足りない場合だけではありません。PHPに設定したメモリ使用量の上限であるmemory_limitに達したときにも起こります。本来はエラーで終わるはずの処理が、PHP内部の状態の不整合によって任意コード実行につながる点が問題です。

実証されたコード実行は、PHPを動かしているプロセスの権限で行われます。この脆弱性だけで、必ずサーバーの管理者権限まで奪われるわけではありません。

CVE-2026-109618:メモリ不足時の処理

PHPはメモリ不足(Out of Memory、OOM)を検知すると、従来はlongjmp()という仕組みで実行中の処理から抜けていました。しかし、内部データの初期化が終わる前に中断すると、終了処理が未完成のデータを参照する場合があります。この不整合がメモリ破壊を起こし、任意コード実行につながります。

例えば、ファイルの送信などで使われるmultipart/form-dataの解析では、受信データの大きさ以上に内部メモリを消費する場合があります。「物理メモリには余裕がある」「HTTPの送信サイズを制限した」というだけでは、すべての経路を防げません。

修正では、OOMによる中断を安全な実行地点まで遅らせる処理と、さらに高いメモリ使用量の上限に達した場合にプロセスを直ちに終了する処理を導入しています。

CVE-2026-109619:リクエストをまたいで残る状態

PHPのワーカープロセスは、同じプロセスで複数のHTTPリクエストを順番に処理することがあります。リクエストが終わると、その処理に使ったメモリは解放されます。

ところが、エラーやセッションに関する内部の参照が残ると、後続のリクエストが解放済みのメモリに触れてしまいます。これをuse-after-free(解放済みメモリの使用)と呼びます。

きっかけはOOMに限りません。致命的なエラーで後始末が中断されたり、終了処理中の警告などによって、一度消した状態が再び設定されたりする経路もあります。修正では、リクエストをまたいで残してはいけない内部状態を適切に初期化・破棄するようにしています。

Apache mod_phpとPHP-FPMの違い

Webサイトへのアクセスは、ApacheやNginxなどのWebサーバーが受け付けます。PHPを使うページでは、そこからPHPのプログラムを実行し、その結果を利用者に返します。mod_phpとPHP-FPMは、このときPHPを動かすための仕組みです。

仕組みPHPの動かし方
Apache mod_phpApacheにPHPを組み込み、Apacheのプロセス内でPHPを実行します。
PHP-FPMWebサーバーとは別にPHP用のプロセスを管理し、ApacheやNginxから受け取った処理を実行します。

プロセスとは、サーバー上で動いているプログラムの実行単位です。PHP-FPMでは、実際にリクエストを処理する子プロセスを「ワーカー」と呼びます。

PHPは、アプリケーションのコードを動かす前に入力データの読み込みなどの開始処理を行い、処理の終わりにはメモリの解放などの終了処理を行います。今回の脆弱性では、開始処理に失敗した後の動作の違いが、攻撃の成立条件に関係しています。

mod_phpは、開始処理に失敗しても終了処理へ進みます。そのため、メモリ不足によってPHP内部に不正な状態が残ると、終了処理がその状態を使ってしまうことがあります。この挙動を利用し、アプリケーションのコードが動く前に攻撃を成立させる経路が実証されました。

一方、PHP-FPMは、開始処理に失敗したワーカーを終了させます。そのため、mod_phpで確認された経路が、そのまま成立するわけではありません。

ただし、リクエストをまたいで状態が残る脆弱性(CVE-2026-109619)では、PHP-FPMでも別の攻撃経路が実証されています。開始処理が成功した後、アプリケーションの処理中のエラーによってPHP内部に不正な状態が残り、同じワーカーが扱う後続のリクエストで悪用されるというものです。

攻撃の成立条件は実行方式やアプリケーション、設定によって異なりますが、PHP-FPMを使っている場合も、修正済みのPHPへの更新が必要です。

引用元:

なぜ今回深刻な問題になったのか

以前からあった兆候と攻撃の実証

過去の記録をたどると、2019年11月に報告されたPHP Bug #78876があります。大量の入力によってメモリ不足が起こり、一時ファイルが正しく削除されない問題で、2020年には修正されています。ただし、この時点で今回の任意コード実行につながる経路まで判明していたわけではありません。

2024年のセキュリティ監査に関連する作業でも、今回につながるOOM処理の問題が認識されました。しかし、当時は具体的な悪用経路が実証されていませんでした。

転機になったのは2026年8月です。米国のセキュリティ企業Califの研究チームは、OpenAIの「Patch the Planet」という脆弱性の発見と修正を支援する取り組みの一環として、7月30日からPHPを調査していました。

Califは複数の任意コード実行につながる経路を発見し、8月11日に最初の報告、14日にPHP側へPoCを共有しました。PoC(Proof of Concept)は、脆弱性が実際に悪用できることを確かめるための検証用コードなどを指します。

この8月の共有は、修正に向けた非公開のやり取りでした。10月にSNSなどで広まったPoCとは別のものです。

以前から兆候があった問題について、実際に攻撃できる経路が示されたことで、影響の大きさが明確になりました。

引用元:

AIが支援した調査

今回の脆弱性調査ではAIも活用されました。Califは過去のPHPの脆弱性に関する知見を手がかりに、AIを使いながら攻撃が成立する条件を調べています。

クラウドセキュリティ企業Wizの研究チーム「Wiz Research」も、独自にPHPの脆弱性を調査しました。Wiz ResearchはAIを使って解析や検証を繰り返し、複数のアプリケーション環境で攻撃が成立することを確認しています。

AIが自動的にすべてを発見したというわけではありません。過去の脆弱性を知る研究者が調査の方向性を考え、AIで分析や検証を進めたことが、今回の発見につながっています。

引用元:

修正版の正式公開前に起きたこと

SNSでの情報拡散

PHPの開発や保守を資金面などから支援する組織「PHP Foundation」によると、2026年10月21日の正式公開に先立ち、脆弱性に関する情報がSNSやオンラインフォーラムに流出しました。

最初に広まったのはCVE番号や公開予定時刻、深刻度に関する情報です。公開時刻は誤っており、CVSSも「10.0」と伝わっていましたが、公式評価は9.2です。PHP Foundationによると、この段階で技術的な詳細は流出していませんでした。

その後、CalifがPoCのデモ動画を誤って公開しました。

動画には複数の対象で攻撃が成立する様子が映っていました。すぐに削除されましたが、コピーがSNS上で広まりました。PHP Foundationは、動画に含まれていた限られた技術情報が、その後のPoC開発を加速させたと説明しています。

その間、防御側も対応を進めていました。Webサイトの通信を保護するサービスを提供するCloudflareは、正式公開前にWAFによる保護を展開しています。WAF(Web Application Firewall)は、Webアプリケーションに向けられた不審な通信を検知・遮断する仕組みです。

セキュリティ対策を施したコンテナイメージを提供する企業Chainguardも、修正済みのPHPを含むイメージを正式公開前に配布しました。コンテナイメージは、アプリケーションと実行に必要なソフトウェアをまとめたものです。

ただし、Chainguardの先行公開は問題にもなりました。PHP Foundationによると、Chainguardには正式公開に備えて修正パッチが事前共有されていましたが、合意された時刻より先に配布したため、攻撃者も修正内容を解析できる状態になったと指摘しています。

こうした経緯を見ると、修正版PHPの正式公開より先に、脆弱性や攻撃に関する情報が広まっていたことは確認できます。

ただし、情報の流出、PoCの公開、攻撃の試行、実際の侵害成功は分けて考える必要があります。情報が拡散されたことだけで、攻撃が成功したとは判断できません。

引用元:

正式公開までに必要だった準備

修正パッチは、正式公開より前にLinuxディストリビューションなどの配布元へ共有されていました。ただし、利用者向けパッケージの準備はまだ続いていました。

修正コードが完成しても、配布元には修正の取り込み、ビルド、検証、配布といった作業が残ります。攻撃方法だけを先に知られてしまうと、利用者がすぐに更新できない状態で攻撃にさらされる可能性があります。

PHP Foundationは、配布の準備時間も確保するため、即時公開ではなく、当初の予定を1日前倒ししたと説明しています。

つまり、「攻撃情報がパッチより先に出た」というのは、修正版が正式に一般公開されるより前だったという意味です。修正パッチそのものは事前に存在しており、Chainguardのように先行配布した企業もありました。

修正が長く停滞した背景

そもそも、修正方針を決めるまでにも時間がかかっていました。

PHP Foundationによると、2024年に問題の兆候が見つかった後、PHPセキュリティチームは複数の修正案を検討しました。しかし、それぞれ後方互換性への影響、新たなサービス停止のリスク、多数の拡張機能への変更といった課題がありました。

PHPの内部処理に詳しい開発者が限られるなか、全員の合意を重視する意思決定も難航し、作業は何度も停滞したとされています。PHP Foundation自身も、判断の仕組みと人手の不足による「構造的な失敗」だったと認めています。

ただし、任意コード実行の影響が明確になった2026年8月11日以降は、修正を最優先にしたと説明しています。「実証済みの重大な攻撃を知りながら、2年間放置した」という理解は正確ではありません。

「人災」と呼べるのか

PHP Foundationが修正方針の決定に問題があったと認めている以上、対応体制に改善すべき点があったことは確かです。ただ、修正そのものの難しさ、動画の誤公開、修正版の先行配布は、それぞれ別の問題として見た方がよさそうです。

先行配布について、ChainguardのCEOであるDan Lorencは、攻撃に関する報告があったことや、自社でも脆弱性を再発見できたことなどを判断の理由に挙げています。修正済みイメージは自社顧客以外にも公開したと説明しています。

これに対して、PHP Foundationの記事を書いたNils Adermannは、共有されていたのは攻撃の試行に関する報告で、成功が確認されたわけではないと反論しています。公開時刻を一社の判断で変えたことも批判しています。

このように判断が分かれていますが、公表された情報だけでは、先行公開によって実際にどれほど被害が増えたのかは分かりません。

PHPのセキュリティ対応には、コミュニティの参加者と、Foundationの資金支援を受ける開発者の両方が関わっています。Foundationは2026年5月にセキュリティ対応を支援するチームを設け、意思決定の進め方も見直しています。

今回の経緯をひとまとめに「人災」と断定するより、修正を難しくした技術的な事情と、改善できたはずの判断や連携を分けて考える必要があると思います。

引用元:

時系列まとめ

関連する問題の報告から攻撃の実証まで

まずは、今回の脆弱性につながる問題がいつ見つかり、攻撃の実証に至ったのかを整理します。2019年の報告は関連する過去の問題で、当時から今回の2つのCVEがすべて判明していたという意味ではありません。

時期出来事
2019年11月28日PHP Bug #78876が報告される。大量の入力によるメモリ不足と、一時ファイルが削除されない問題が記録された
2020年5月Bug #78876の修正が記録される
2024年セキュリティ監査に関連する修正作業で、今回につながるOOM処理の問題が認識される。当時は具体的な悪用経路が実証されていなかった
2026年7月30日CalifがPHPの監査を開始
2026年8月1日Califが、任意コード実行につながる複数の経路を発見
2026年8月11日CalifがPHPへ最初の報告。Foundationは、この日以降、修正を最優先にしたと説明
2026年8月14~15日CalifがPHP側へPoCを非公開で共有し、PHP側が動作を確認
2026年8月21日Califが2件目の問題をPHPへ報告
2026年8月24日・9月18日Wiz、OpenAIからも追加の攻撃経路が報告される

引用元:

情報の拡散から修正版の正式公開まで

続いて、正式公開直前の動きです。以下の時刻は日本時間(JST)に統一しました。10月17日はAWSが公表した観測日で、時刻は示されていません。

日時出来事
10月17日(AWS記載の日付)AWSがハニーポット(攻撃を観測するための監視用環境)で、PHP2Shellを狙った攻撃試行を確認。後に公表した
10月21日 0時ごろCVE番号、誤った公開時刻、誤ったCVSSスコアがSNSなどで流通。この段階では技術的な詳細は流出していなかったとFoundationは説明
10月21日 4時30分PHPが事前告知を公開。正式公開を10月22日から21日へ1日前倒し
10月21日 5時ごろFoundationによると、CalifがPoCのデモ動画を誤公開。削除後もコピーがSNSで拡散
10月21日 11時ごろAWSがPoCを確認。11~17時には、追加の攻撃試行も観測
10月21日 12時2分Cloudflareによると、無料・有料のWAF利用者向けに既定の保護を提供
10月21日 16時41分Chainguardが、修正を含むコンテナイメージを先行公開
10月21日 23時PHPの修正版と脆弱性情報が正式公開
10月22日国内のセキュリティ対応を支援するJPCERT/CCが注意喚起を公開

デモ動画の誤公開は正式公開の約18時間前、AWSがPoCを確認したのは約12時間前です。

PHPセキュリティチームは、正式公開時点で確認した公開PoCの中に、実際に機能する攻撃コードを見つけられなかったと説明しています。AWSも、観測した攻撃試行が実環境で成功するものだったかは不明としています。研究者が非公開の環境で攻撃を実証したこととは区別する必要があります。

さらに、10月17日の攻撃試行は、動画や先行イメージの公開より前に観測されています。この試行の原因を、それらの公開に求めることはできません。

引用元:

PHPを使う開発者と運用者が確認すること

修正済みPHPへの更新

最初に公開された修正版は、PHP 8.2.35、8.3.36、8.4.27、8.5.12です。利用している系統の修正版、またはOSなどの配布元が修正を取り込んだパッケージへ更新する必要があります。

確認するのは、本番環境でWebリクエストを実際に処理しているPHPです。コマンドラインでphp -vを実行した結果だけでは、PHP-FPMやmod_php、コンテナイメージなどが更新済みかどうかは分かりません。更新後は、稼働中のワーカーやコンテナにも修正を反映させます。

また、OSの配布元が、元のバージョン番号を維持したまま修正だけを取り込む「バックポート」もあります。例えばUbuntu 24.04 LTSでは、修正済みのphp8.3-fpmとして8.3.6-0ubuntu0.24.04.13が案内されています。

このような場合、PHP本体のバージョン番号だけでは修正の有無を判断できません。利用しているOSや製品のセキュリティ告知と、パッケージのリビジョンまで確認しましょう。

引用元:

更新前の緩和策

PHPの公式アドバイザリには、すぐに更新できない場合の緩和策として、memory_limit=-1やsession.upload_progress.enabled=0などの設定が挙げられています。

ただし、これらは特定の攻撃経路を減らすための設定です。例えばmemory_limit=-1はPHPのメモリ上限を解除するため、別のメモリ枯渇リスクにつながる可能性もあります。設定の影響を確認したうえで検討する必要があります。

WAFや設定変更だけでは対策が完了しません。PHP公式も、完全に対策するには修正版への更新が必要だと説明しています。

引用元:PHP: News Archive - 2026

正式公開前も含めた侵害調査

更新と併せて、攻撃を受けた痕跡がないかも確認しておきたいところです。JPCERT/CCは、次のような項目を調査の手掛かりに挙げています。

  • 不自然に長い値や、異常な形式の値を持つPHPSESSIDレスポンスCookie
  • 不審なmultipart/form-dataリクエストと、その前後のメモリ不足やHTTP 500エラー
  • PHPワーカーの予期しない異常終了や、頻繁な再起動
  • 不審なプロセス、外部通信、ファイルの作成

AWSは10月17日の攻撃試行を確認しているため、調査対象を正式公開日の10月21日以降に限定するのは避けたいところです。AWSも、少なくとも10月17日からの記録を調べるよう勧めています。

こうした痕跡が見つからなくても、侵害されていないとは断定できません。ログに記録されない攻撃経路も考えられます。侵害が疑われる場合はログなどを保全し、影響範囲の調査や必要な隔離を進めます。

引用元:PHPにおける複数の脆弱性(CVE-2026-109618、CVE-2026-109619)に関する注意喚起

まとめ:PHPを更新し続けられる運用

PHP2Shellでは、脆弱性そのものに加え、修正案を決める体制や、各社の公開時期をそろえる難しさも見えてきました。

今回の件で、運用する側として特に考えておきたいのは、脆弱性が公開される前からPHPを更新し続けられる状態にしておくことです。

PHPの各バージョンにはEOL(End of Life、サポート終了)があります。2026年10月時点で、PHP 8.1以前はPHPプロジェクトの通常のサポート対象外です。今回もOSの配布元や長期サポート(LTS)の提供元によるバックポート、特例で公開された古いバージョン向けの修正ソースなどを、環境ごとに確認する必要がありました。

EOLを迎えたPHPにも、修正が提供される場合はあります。ただし、利用中の環境ですぐに適用できるパッケージがあるとは限りません。修正の入手先を調べたり、依存ライブラリを更新したり、移行後の動作を確認したりする作業が、緊急対応に追加される可能性があります。

PHP 8.2も、公式のセキュリティサポートは2026年12月31日で終了する予定です。今回の修正版へ更新すると同時に、次のバージョンへの移行も考える必要があります。

PHP本体だけでなく、フレームワークや拡張機能、OSとの互換性を普段から確認し、EOLより前に移行を進めておく。そうすることで、次に重大な脆弱性が公開された際、古い環境の大規模な移行と緊急対応を同時に進めずに済みます。

日頃からPHPを更新しておくことは、セキュリティ対策であると同時に、将来の緊急対応にかかる工数を減らすことにもつながると考えています。

引用元: