PHPの認証不要RCE「php2shell」とは — CVE-2026-109618/109619の仕組みと今すぐやる対処
はじめに
10 月 21 日夜(日本時間)、PHP に認証なしでリモートからコードを実行される脆弱性 2 件(CVE-2026-109618 / CVE-2026-109619)の修正版が公開されました。どちらも CVSS v4.0 で 9.2 です。研究者や Wiz の記事では「php2shell」と呼ばれています。
アプリのコードに穴があるのではなく、PHP 本体の不具合です。そのため WordPress でも Laravel でも、PHP で動いていれば対象になり得ます。国内では公開の前後に 200 を超える組織がサービスを止めたり緊急メンテナンスに入ったりしました。この記事では、何が壊れているのか、なぜ設定の変更だけでは防げないのか、何をすればよいのかを順に整理します。
何が起きたのか
修正版は次のとおりです。
| 系列 | 修正版 |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
PHP Foundation によると、2 件の中身は次のとおりです。
- CVE-2026-109618(メモリ不足による破損):リクエストが悪いタイミングで
memory_limitに達すると、作りかけの内部データが残り、あとで正しいデータとして扱われてしまう。Apache + mod_php では、アプリのコードが動く前の段階で、認証なしのリクエストから標準設定のままコード実行が実証された。PHP-FPM でも、アプリ側の処理経路を通じたコード実行が確認された - CVE-2026-109619(前のリクエストの状態が残る):致命的エラーが悪いタイミングで起きると、内部の状態が前のリクエストのメモリを指したまま残る。同じワーカーが次のリクエストを処理するとき、すでに解放されたメモリを使ってしまう(Use After Free)
Wiz は、最新の WordPress・Drupal・Joomla のコンテナイメージに対して認証なしのコード実行を実演しました。影響は PHP 5.4 までさかのぼるとしています。GMO Flatt Security は、どの版が影響を受けるかの判定は難しいので、5.x〜8.x を広く影響ありと考えるべきだとしています。
経緯も異例でした。Wiz の時系列では、最初の発見が 8 月 19 日、PHP のセキュリティチームへの報告が 8 月 24 日です。修正の公開は当初 10 月 22 日の予定でしたが 21 日に前倒しされ、その 21 日の未明に脆弱性の情報が漏れました。同じ日の昼には「悪用できる」とするコードが出回り始めています。piyolog によると、Cloudflare は修正の公開前に既知の攻撃経路向けの WAF ルールを全顧客に展開しました。同じく piyolog の集計では、国の機関・自治体・金融機関・ゲーム会社・ホスティング / IT サービスなど国内 211 組織が停止や緊急メンテナンスを告知しました。
技術的な背景 — 「次のリクエスト」に壊れた状態が残る
前提:PHP のワーカーは使い回される
PHP は「1 リクエストごとにまっさらな状態から始まる」と考えられがちです。実際には、mod_php や PHP-FPM のワーカープロセスは多数のリクエストを順番に処理します。リクエストが終わるとそのリクエスト用のメモリはまとめて解放されますが、プロセス全体で使う変数(グローバルな状態)は残ります。
今回の問題は、この「解放されたメモリ」と「残る変数」の食い違いです。メモリ不足や致命的エラーでリクエストが途中で打ち切られると、メモリは解放されるのに、グローバル変数はそのメモリを指したまま残ります。次のリクエストで攻撃者がそのメモリに自分のデータを置けば、PHP はそれを正しい内部データだと思って使います。GMO Flatt Security は、壊れたデータを残す側を Producer、あとでそれを使う側を Consumer と呼んで説明しています。
入口は「セッションのアップロード進捗」
既知の Producer の代表が、標準で有効な Session Upload Progress 機能です。これはファイルのアップロード中に進捗をセッションへ書き込む機能で、multipart 形式の POST を受け取った時点、つまりアプリのコードが動く前に処理されます。Wiz によると、アプリが session_start() を一度も呼ばなくても動きます。WordPress でも Laravel でも成立するのはこのためです。
Wiz は 4 つの不具合を挙げています。たとえば、メモリ不足でヒープが解放されたあとも、セッション ID を指す内部ポインタが残る不具合があります。次の multipart リクエストでは、解放後のメモリの中身が PHPSESSID クッキーに入って返ってきます。攻撃者はこれでメモリの配置を知ることができ、ASLR(アドレスの配置をランダムにする防御)を回避する材料になります。GMO Flatt Security が研究者の公開した動画を分析したところ、検証環境(Ubuntu 26.04 / PHP 8.5.4 / mod_php)で約 22.6 秒で www-data 権限のコマンド実行に至っています。
なぜ設定の変更では防ぎきれないのか
公式アドバイザリは、一時しのぎの設定をいくつか挙げています。
session.upload_progress.enabled=0(php.ini や FPM のプール設定で行う。ini_set()や.user.iniには頼らない)- PHP 8.5 では
fatal_error_backtraces=0 memory_limit=-1にする、post_max_sizeを下げてサーバーやプロキシでもリクエストの大きさや multipart のパート数を制限する- 設定を変えたら全ワーカーを再起動する
GMO Flatt Security は、multipart の POST が不要なら止めることも挙げています。
それでも「完全には防げない」とされるのは、原因が特定の機能ではなく、「途中で打ち切られたときに後片付けが漏れる」というエンジン全体の性質にあるからです。アップロード進捗の機能を切っても、別の Producer と Consumer の組み合わせが残る可能性があります。php.net のアドバイザリも、アップロード進捗を切る対策について「確認済みのセッション経由の経路は防ぐが、他の変種は防げない」としています。完全な対処は修正版への更新だけです。
エンジニアへの影響と対処
次の順に確認するのが確実です。
- PHP を修正版に上げる:ディストリビューションのパッケージを使っている場合は、修正済みのパッケージが出ているか確認します。piyolog の集計では、Ubuntu(22.04〜26.10)・Arch は対応済み、Debian は trixie / bookworm のみ、Alpine は edge のみ対応済みで、Amazon Linux 2023 は 10/22 未明の時点で修正待ちでした。Remi リポジトリは公開当日の時点で未更新でした
- コンテナイメージは作り直す:ベースイメージが修正版になっても、ビルド済みのイメージは古い PHP のままです。修正版のベースイメージでビルドし直し、デプロイし直します
- 8.1 以前を使っている場合:PHP プロジェクトとしての修正版は出ていません。セキュリティチームが 7.4 / 8.0 / 8.1 向けに最小限の修正を出していますが、サポート中の系列へ移るのが本筋です
- すぐ更新できない場合:上の設定変更と WAF のルールで時間を稼ぎます。ただし、どちらも更新の代わりにはなりません
- 更新後に調べる:アプリのログにはほとんど痕跡が残りません。Wiz は「multipart リクエストのあとにメモリ不足エラーや 500 エラーが続く」「
PHPSESSIDクッキーが異常に長い・形がおかしい」「PHP ワーカーが理由なく入れ替わる」点を見るよう勧めています。GMO Flatt Security は、侵入された疑いがあれば、サーバーが持つ権限(IAM ロールやサービスアカウント)を使って他のシステムへ広がっていないかも確認するよう勧めています
なお、Apache の標準のアクセスログにはリクエストの本文も multipart かどうかも記録されません。自分の VPS のログを調べた筆者も「今回の攻撃の有無はこのログでは判断できない」と書いています。「ログに何もないから大丈夫」とは言えないので、更新を先に済ませるのが正解です。
まとめ
- PHP 本体に認証不要のコード実行の脆弱性が 2 件。修正版は 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12
- メモリ不足や致命的エラーで打ち切られたリクエストの壊れた状態が、同じワーカーの次のリクエストで使われる
- 入口の代表は標準で有効なアップロード進捗の機能で、アプリのコードより前に動くため、フレームワークを問わない
- 設定変更と WAF は一時しのぎ。更新とイメージの作り直しが唯一の完全な対処
Wiz は発見から攻撃コードの調整までを AI で進め、1 人が 1 週間でこなしたと述べています。PHP Foundation も、AI を使った報告の検証や外部による監査(Calif・Trail of Bits)を進めていると説明しています。古いランタイムの深い不具合を AI が掘り当てる流れは今後も続くとみられ、「更新をすぐ出せる体制」そのものが問われることになります。
今日のその他のニュース
LiteLLM 1.107.0 が PyPI 上で改ざん
LLM の API をまとめて呼べる Python ライブラリ LiteLLM の 1.107.0 に、認証情報を盗むコードが入っていました。site-packages に .pth ファイルなどを置き、LiteLLM を使わない Python プロセスでも起動のたびに動きます。SSH 鍵、クラウドの認証情報、Claude Code などのトークンが対象です。入れていた場合は、盗まれ得る認証情報をすべて作り直すのが安全です。
Node.js のセキュリティリリース
v26.12.1 / v24.22.1 / v22.23.4 が出ました。Brotli の展開処理によるリモートでのコード実行や、TLS 証明書のホスト名確認をすり抜ける問題など、深刻度「高」が 4 件あります。鍵が漏れた eMudhra の中間 CA の件を受けて、CA 証明書の一覧も更新されています。
ソース
- PHPの重大な脆弱性「php2shell」(CVE-2026-109618、CVE-2026-109619)の概要と対応指針(GMO Flatt Security)
- PHP2Shell: AI uncovers critical RCE vulnerabilities affecting 70% of the Internet (Wiz Blog)
- Today’s PHP Security Release, and How We’re Strengthening PHP Security (The PHP Foundation)
- PHPの2件の深刻な脆弱性(CVE-2026-109618、CVE-2026-109619)についてまとめてみた(piyolog)
- 【PHP脆弱性php2shell】「23:15から乗っ取り」「15分でAIが攻撃コード?」は本当か、自分のVPSのログで検証(ITmedia オルタナティブ・ブログ)
- Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor (SafeDep)
- PHP Security Advisory 2026-10-21 (php.net)
- Node.js — Wednesday, October 21, 2026 Security Releases