
PHP本体に、認証なしでリモートコード実行につながる「PHP2Shell」と呼ばれる重大な脆弱性が見つかりました。攻撃が成立するとWebサーバー上で任意のコードを実行される可能性があり、単なるWebサイト改ざんでは済まない問題です。修正版は2026年10月21日23時(日本時間)に公開されましたが、すべてのサーバーを即座に更新できるとは限りません。そこで今回は、まずこの脆弱性がどのような危険をもたらすのかを確認したうえで、WAFやCDN、メンテナンスページなどの対策が実際にどこまで有効なのかを深掘りしていこうと思います。
PHP2Shellが悪用されると何が起きるのか
今回のCVE-2026-109618とCVE-2026-109619は、いずれもCVSS v4.0で9.2のCriticalと評価されています。特に深刻なのは、事前に管理者アカウントを盗んだり、WordPressへログインしたりしなくても、外部から送ったHTTPリクエストをきっかけにPHPプロセス上でコード実行へつながる可能性がある点です。
攻撃に成功した場合、コードは原則としてPHPを実行しているWebワーカーの権限で動きます。つまり、必ずroot権限を取られるという意味ではありません。しかしWebワーカーから読める設定ファイルやアプリケーションファイル、接続可能なデータベース、APIなどは攻撃対象になり得ます。さらにCVE-2026-109619では、認証なしのUse After Freeだけでなく、メモリ情報の漏えいとRCEが確認されています。

Webアプリケーションの設定ファイルには、データベースの接続情報や外部サービスの認証情報が置かれていることもあります。Webワーカーが書き込み可能な領域があれば、ファイル改ざんやWebShellの設置、マルウェアの実行などへ発展する可能性もあります。
「PHPの脆弱性だから、Webサイトが少し壊れる程度」と考えない方がよいでしょう。
2つの脆弱性はPHPのかなり深い部分にある
PHPは2026年10月21日、PHP 8.5.12、8.4.27、8.3.36、8.2.35を公開しました。PHPプロジェクトは、これらの修正版への更新について「完全な緩和策は存在せず、更新が唯一の安全な選択」としています。
今回難しいのは、WordPressやLaravelなどアプリケーションの処理よりも低いレイヤーに問題があることです。アプリケーション側で入力値をチェックしているから大丈夫、という種類の脆弱性ではありません。
CVE-2026-109618はメモリ不足処理が起点になる
CVE-2026-109618は、PHPがOut Of Memory(OOM)になった際の処理に関係しています。特定のタイミングでメモリ確保に失敗すると、完全に初期化されていない内部状態を残したまま処理を抜け、その後の終了処理でその状態を正しいデータとして扱ってしまうことがあります。
今回特に注目されているのがmultipart/form-dataです。PHP公式アドバイザリでは、通常のpost_max_size以内に見えるリクエストであっても、multipart内部に大量のヘッダーを持たせたり、空のファイルフィールドやネストしたフィールドを組み合わせたりすることで、PHP内部では想定以上のメモリを消費できるケースが説明されています。
Apacheのmod_phpでは、アプリケーションコードが動き始める前のリクエスト初期化処理でOOMを起こし、その後のshutdown処理からRCEへつながることが確認されています。つまりWordPress側へ届く前に問題が起こり得ます。
CVE-2026-109619は前のリクエストの状態が残る
もう一つのCVE-2026-109619では、あるリクエストが使用していた内部状態が適切にリセットされず、すでに解放されたメモリを後続のリクエストが再利用する可能性があります。
攻撃では「状態を残すリクエスト」と「その状態を利用する後続リクエスト」が同じPHPワーカーへ到達する必要があります。このためワーカー数を増やせば成功確率は下がりますが、問題自体がなくなるわけではありません。mod_phpだけでなく、セッションライフサイクルを利用した経路ではPHP-FPMでもRCEが確認されています。
PHPでは1つのワーカーが多数のリクエストを繰り返し処理するのが普通です。この効率のよい仕組みが、今回は「前のリクエストの状態が次へ残る」という攻撃条件にも関係しています。
「メンテナンスページを出したから安全」とは限らない
脆弱性の情報が出た直後、一時的にサイトをメンテナンス状態へ切り替えた事業者もありました。サービスを止めること自体は間違った対応ではありません。問題は「どこで止めているのか」です。
WordPressのメンテナンスプラグインなどを使い、PHPやWordPressがリクエストを処理した後で「現在メンテナンス中です」というHTMLを返しているだけなら、今回の脆弱性対策にはならない場合があります。
攻撃者に見える画面がメンテナンスページでも、その裏側で脆弱なPHPが実行されていれば攻撃面は残っています。

メンテナンスを暫定対策として使うなら、ロードバランサー、Webサーバー、CDNなどPHPより前のレイヤーで通信を止める必要があります。CDNから静的なメンテナンスページだけを返し、POSTを含めてオリジンへ通信を送らず、さらにオリジンIPへの直接アクセスも遮断できれば、かなり強い暫定対策になります。
逆に、GETだけをメンテナンスページへ差し替えてPOSTはオリジンへ通る構成や、オリジンサーバーへ直接アクセスできる構成では十分ではありません。
判断基準は「メンテナンス画面が表示されているか」ではなく、外部から脆弱なPHPまでリクエストが到達できるかです。
WAFやCDNだけで完全に防ぐこともできない
今回のような緊急脆弱性ではWAFが重要になります。ただし「WAFが入っているからPHPを更新しなくてよい」という意味ではありません。AWSもPHP2Shell向けのWAF緩和策を公開していますが、PHPのアップグレードを最優先とし、WAFをパッチ適用までの露出を下げる多層防御として位置付けています。
AWSは、2つの脆弱性のうち一部にはWAFから見えないサーバー内部の状態が含まれているため、Web Application Firewallだけではカバーできないと明記しています。WAFはHTTPリクエストを見ることはできますが、PHPワーカー内部のメモリ状態や、サーバー側のINI設定までは見られません。

WAFで止めやすい部分もある
一方で、現在確認されている攻撃経路の一部には特徴があります。
multipart/form-data、PHP_SESSION_UPLOAD_PROGRESS、大きなPOST本文、短時間の繰り返し試行などです。AWSはこれらに対してWAFルールを適用し、パッチ適用までの攻撃面を減らす方法を公開しています。
ファイルアップロードをまったく使わないWebサイトであれば、multipart/form-data自体をフロント側で拒否するという方法もあります。AWSも、multipartを使用しないアプリケーションであればエッジでブロックすることを緩和策として挙げています。
ただし、multipart内部の小さなヘッダー群がPHP内部で大きなメモリ消費へ膨らむ「header amplification」のようなケースは、単純な本文サイズ制限だけでは完全に見抜けません。
WAFはかなり役に立ちますが、万能ではありません。
PHPを更新できない数時間をどう守るか
最終的には修正版へ更新する必要があります。しかし現実の運用では、数十台、数百台のPHPサーバーについて、対象バージョンを調べ、パッケージを用意し、テストし、順番に更新していく必要があります。
その間の露出を小さくするため、WAFだけでなくNginxやPHP側でも防御を重ねることができます。
以下は恒久対策ではなく、修正版へ更新するまでの暫定緩和策です。
NginxでmultipartをPHPへ渡さない
アプリケーションがファイルアップロードなどmultipart/form-dataを一切使用しない場合は、NginxでPHPへ届く前に拒否できます。

たとえば次のような設定です。
map $http_content_type $block_multipart {
default 0;
~*^multipart/form-data(?:\s*;|$) 1;
}
server {
# 既存設定...
if ($block_multipart) {
return 403;
}
}これはあくまでmultipartを必要としないサイト向けです。WordPressのメディアアップロードや問い合わせフォームのファイル添付など、正規にmultipartを使う機能があれば当然その機能も止まります。
また、リクエスト本文そのものの上限をNginx側で設けておくこともできます。
server {
client_max_body_size 8m;
}client_max_body_sizeを超えるリクエストについて、Nginxは413を返します。Nginx公式のデフォルト値は1MBですが、実際の値はアプリケーションに必要なアップロードサイズに合わせる必要があります。
ただし、今回の脆弱性では小さなmultipartリクエストがPHP内部で大きくメモリを使うケースもあるため、本文サイズを制限しただけで安全になるわけではありません。
php.iniにも暫定緩和策がある
PHP公式アドバイザリとAWSは、すぐにアップデートできない環境向けとしていくつかの設定変更を案内しています。
代表例は次のようになります。
; CVE-2026-109618 の暫定緩和
memory_limit = -1
; 必要以上に大きなPOSTを許可しない
post_max_size = 8M
; セッションアップロード進捗を使用しない場合
session.upload_progress.enabled = 0
; PHP 8.5のみ
fatal_error_backtraces = 0
; 調査用
log_errors = On
error_reporting = E_ALLここで一番注意したいのがmemory_limit=-1です。
普通に見ると「メモリ上限を無制限にする方が危険では?」と思いますよね? 今回この値が推奨されている理由は、攻撃者がPHPの予測可能なmemory_limit到達を利用して脆弱なOOM処理を発生させる経路を減らすためです。PHP公式もこれをCVE-2026-109618の主要な設定ベースの緩和策としています。
ただし、メモリを無制限に消費させてよいという意味ではありません。AWSはPHP自身のmemory_limitを無効にする代わりに、コンテナやcgroup側でメモリ制限を持たせることを案内しています。またRLIMIT_ASやRLIMIT_DATAは、逆に脆弱なmmap()失敗経路を引き起こす可能性があるため使用しないよう警告されています。
post_max_sizeについてAWSは、アップロードを受け付けない環境なら8MB、受け付ける場合でも32MB程度の小さな値を一例として示しています。環境に応じて必要最低限に設定するのがよいでしょう。
設定変更後はPHPワーカーの再起動も必要です。
PHP-FPMではワーカーを毎回捨てる方法もある
CVE-2026-109619では、前のリクエストの状態と後続リクエストが同じワーカーでつながることが攻撃条件になります。
PHP-FPMを使っていて、性能低下を一時的に許容できるのであれば、
pm.max_requests = 1とし、1リクエスト処理するたびにワーカーをリサイクルする方法もPHP公式とAWSから挙げられています。
当然ながらワーカー生成回数が増えるため、通常運用の推奨設定という意味ではありません。緊急時の暫定策です。

実はこの問題、2024年に最初の兆候が見つかっていた
今回のPHP2Shellでもう一つ興味深いのが、脆弱性が発見されてからパッチ公開までの経緯です。
PHP Foundationは2026年10月21日に、かなり率直な振り返りを公開しています。それによると、CVE-2026-109618につながるOOM問題の最初の兆候は、今回初めて見つかったものではありませんでした。
2024年の外部セキュリティ監査で兆候が見つかる
2024年、PHPは数年ぶりとなる外部セキュリティ監査を受けました。PHP FoundationがSovereign Tech Agencyから資金を得て、OSTIFを通じてQuarkslabが監査を実施しています。
その監査で報告された別の問題を修正している途中、PHP Foundationと契約していたPHPコア開発者が、今回CVE-2026-109618へつながるOOM問題の最初の兆候を発見しました。
2024年の時点ですでに、このOOM問題を悪用できる可能性自体は考えられていました。
しかし、その時点では実際にRCEへつながる具体的な攻撃経路が確認できていませんでした。さらに、目の前には影響が明確な別の脆弱性もあり、今回の問題への対応は優先順位を落としていきました。
修正方法は考えられていたが、どれも副作用があった
問題を単純に無視していたわけではありません。
PHP Security TeamではOOM処理を修正するために複数の方法が検討されました。しかし、それぞれに、
- 後方互換性を壊す
- 新たなDoSリスクを生む
- 多数のサードパーティ拡張側にも変更を要求する
といった問題がありました。
PHP Security Teamは合意を重視する意思決定方式を取っていました。その結果、「間違った修正を出した場合の影響」への懸念から決断できず、修正作業は何度も止まり、再開する状態が数か月続いたと説明されています。
PHP Foundation自身が、この遅延についてセキュリティチームの意思決定プロセスとリソース不足による「structural failure(構造的な失敗)」だったと認めています。
この表現をFoundation自身が使っているのは、かなり印象的です。
2026年になってRCEが現実のものになった
状況が大きく変わったのが2026年です。
PHP Foundationが参加したOpenAIのPatch the Planetプログラムを通じて、Califが7月30日からPHPを監査しました。そして8月11日、Califの研究者が2024年に確認されていたOOM問題と同じ根本原因から、無条件RCEが成立することを報告します。
同じ8月11日にはOpenAIも独立して同じ根本原因を報告し、8月24日にはWiz、9月18日にはOpenAIからさらに別の攻撃経路が報告されました。ここで初めて、2024年に「理論上問題になるかもしれない」と考えられていたものが、現実にインターネット上のサーバーを攻撃できるCriticalな脆弱性であることが明確になりました。
8月11日以降、PHP Foundationはこの修正をセキュリティ作業の最優先事項とし、複数人がフルタイムで対応しています。
公開直前には情報漏れも起きた
当初、修正版の公開は10月22日14時UTCに予定されていました。
ところが10月20日、CVE番号がSNSやフォーラムで流出しました。さらにProof of Conceptの一部情報が広まり、公開予定は1日前倒しされ、10月21日14時UTC、日本時間23時に変更されます。
さらに公開当日の07:41 UTCには、修正版を事前共有されていたChainguardがembargoを破り、修正版を含むイメージを公開したとPHP Foundationは説明しています。攻撃者がバイナリ差分から修正内容を解析できる状態になったため、予定された協調開示はかなり緊迫したものになりました。

近年はAIを使った脆弱性解析も進んでいるため、パッチ公開からexploit作成までの時間はさらに短くなっています。
「パッチが出てからゆっくりアップデートすればよい」という運用は、今後さらに難しくなるのかもしれません。
WAFの価値は「絶対に防ぐ」だけではない
PHP2Shellでは、最終的な対策はPHPのアップデートです。PHP FoundationもAWSも、この点については非常に明確です。
それでもWAFには大きな意味があります。
脆弱性情報が公開された瞬間に、数十台、数百台のサーバーを同時に更新することはできません。対象サーバーの棚卸し、パッケージの準備、テスト、再起動、動作確認までにはどうしても時間がかかります。
その数時間、あるいは数日をどう守るか。
既知の攻撃パターンをWAFで止める、使わないmultipartをNginxで拒否する、リクエストサイズを制限する、PHPの危険な機能を一時的に無効化する。複数の防御を重ねることで、修正版の適用が完了するまで攻撃者に与える機会を減らすことができます。
レッドボックスでもWAFはCDNのエッジでリクエストを検査し、オリジンサーバーへ通信が到達する前に攻撃を遮断します。しかし、今回のようなPHP内部のメモリ管理上の脆弱性について「WAFがあれば完全に安全」とは言えません。
WAFはパッチの代用品ではありません。
ただ、根本対策までの時間を稼げるかどうかは、実際のインシデント対応では非常に大きな違いになります。
最後はPHPを直す、でもそこまでをどう守るか
今回のPHP2Shellで最優先なのは、修正版PHPへの更新です。
CDNを使っているから安全、WAFがあるから安全、メンテナンス画面を表示しているから安全、という話ではありません。特にPHPやCMS自身でメンテナンスページを表示しているだけなら、今回のようにアプリケーションより前のPHP内部で発生する問題には対応できません。
しかし根本対策が必要だからといって、暫定対策に意味がないわけでもありません。
WAF、CDNでのオリジン遮断、Nginxでのmultipartや本文サイズの制限、PHP側の暫定設定を組み合わせれば、修正版を適用するまでのアタックサーフェスをかなり狭められます。
そして今回の経緯を見ると、もう一つ考えておきたいことがあります。
問題の兆候は2024年にすでに見つかっていました。しかし当時は具体的なRCE経路がなく、修正には大きな互換性上の判断が必要でした。その間にAIを含む脆弱性解析技術が進み、2026年には複数の研究チームが同じ問題から現実のRCEを組み立てています。
脆弱性対策では「完全に防げる製品を導入する」ことだけではなく、未知の攻撃が現実になった瞬間から根本対応が終わるまで、どれだけ早く防御レイヤーを追加できるかも重要になっています。


相次ぐ不正アクセス、攻撃はどこから始まる? 脆弱性スキャンとWAF・IP Reputationで考える入口対策
急増するAIクローラー、全部ブロックして大丈夫? CDN・WAFで考えるAIクローラー対策
CDNとWAFが選ばれる理由(セキュリティ対策)
CDN 料金 一覧2017年(高いCDNと安いCDNの違い)