PHP2Shell(CVE-2026-109618 / CVE-2026-109619)とは - PHP 本体の認証不要 RCE 2件の危険度と構成別の対応

PHP2Shell(CVE-2026-109618 / CVE-2026-109619)とは - PHP 本体の認証不要 RCE 2件の危険度と構成別の対応

作成日:
読了:約30分

2026年10月21日、PHP の開発チームはサポート中の全ブランチで緊急のセキュリティリリース(8.5.12 / 8.4.27 / 8.3.36 / 8.2.35)を出しました。修正されたのは、認証なしのリモートコード実行(RCE)につながる2件の脆弱性、CVE-2026-109618 と CVE-2026-109619 です。研究者がこの2件を組み合わせた攻撃コードに付けた名前から、PHP2Shell とも呼ばれています。

PHP のアプリケーションではなく、PHP 本体(php-src)の脆弱性です。WordPress や Laravel のバージョンに関係なく、Web リクエストを処理する PHP はすべて影響を受ける可能性があります。この記事では、2件の仕組みと危険度を一次情報で整理し、サーバーの構成ごとに何をすればよいかをまとめます。

まず結論 - やること

  1. PHP を修正版に更新する。8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 以降(OS のパッケージなら、各ディストリビューションの修正版)。php.net は「更新だけが完全な対策」としています。
  2. 更新後に、PHP を動かしているプロセスをすべて再起動する(Apache、PHP-FPM、FrankenPHP など)。古いワーカーが残っていると直りません。
  3. すぐに更新できないなら、緩和策を入れる。session.upload_progress.enabled=0 など(後述)。ただし緩和策だけでは安全になりません。
  4. 8.1 以前は、サポート中の版へ上げる。PHP プロジェクトからの正式な修正版のリリースはなく、ディストリビューションや LTS ベンダーのバックポートが頼りです。

WARNING

php -v の表示だけで判断しないでください。Ubuntu や Debian、RHEL などの OS のパッケージは、修正を取り込んでもバージョン番号が変わらないことがあります(例: Ubuntu 24.04 は 8.3.6 のまま修正済みのパッケージが出ている)。確認方法は後述の「更新できたかを確かめる」を参照してください。

PHP2Shell とは

PHP2Shell は、2件の CVE をまとめた通称です。PHP 公式(php.net)はこの名前を使っていません。

  • 名前の出どころ: Wiz Research が、WordPress・Drupal・Joomla に対する認証なしの RCE を実証するために2件を組み合わせた攻撃スクリプトを「php2shell」と名付けました(Wiz のブログ、php2shell.com)。同じ日に Calif も「PHP2Shell」の解説を公開しています(Calif)。
  • 報告者: GitHub のアドバイザリのクレジットには Calif、Wiz、OpenAI の研究者などが並んでいます。PHP Foundation のブログによると、最初の報告は8月11日の Calif からで、OpenAI も同じ原因を別に報告し、その後 Wiz と OpenAI が別の攻撃経路を報告しました。
  • 国内では、IPA が「これらの脆弱性の組み合わせは『PHP2shell』と呼ばれています」と注意喚起しています(IPA)。

タイムライン

日時(UTC)できごと
2026-08-11Calif が最初の報告(PHP Foundation のブログ)
2026-10-20 15:00 頃CVE 番号が、誤った公開時刻と誤った CVSS 10.0 を付けて出回る
2026-10-20php.net が「重大なセキュリティリリースを予告」。両方とも CVSS v4.0 で 9.2 と告知
2026-10-21 14:008.5.12 / 8.4.27 / 8.3.36 / 8.2.35 と 8.6.0 RC4 を公開(当初予定の10月22日から前倒し)
2026-10-22IPA と JPCERT/CC が注意喚起
2026-10-23php.net が session upload progress に関する追加情報を公開
2026-10-26php.net が Windows 版のビルドを更新(同梱の Brotli の脆弱性の修正)

公開が前倒しになったのは、情報が予定より早く漏れたためです(PHP Foundation のブログ)。日本時間では10月21日 23:00 の公開でした。

CVE-2026-109618 - RCE via OOM corruption

GHSA-w8hw-w9fx-j79w の内容を要約します。

  • 仕組み: PHP はメモリ不足(OOM)になると、処理を途中で打ち切って抜けます。内部のデータを初期化している途中で打ち切られると、不完全なデータが残り、リクエストの後片付けの処理がそれを正しいものとして扱ってしまいます。
  • OOM の起こし方: 攻撃者は細工した multipart のリクエスト(ファイルのアップロードと同じ形式)を送って、PHP がリクエストの本文を解析する段階でメモリを使い切らせます。Content-Length を使わないリクエストは post_max_size の最初の確認をすり抜けること、multipart のパートごとのヘッダー数に上限がないことなどが使われます。
  • 認証: 不要。影響は「Web サーバーのワーカーの権限での、認証なしのリモートコード実行」です。

構成によって条件が違います。

構成GitHub のアドバイザリの評価
Apache の mod_phpリクエストの開始に失敗しても後片付けを必ず実行するため、アプリケーションのコードが動く前に悪用できる。既定の入力・メモリの制限と通常の prefork 構成で、HTTP 越しの RCE を確認済み
PHP-FPM開始に失敗すると子プロセスごと終了するので、上の経路は成り立たない。ただし通常の処理中の OOM から影響を受けうる。ソースの解析では影響ありと判断されているが、FPM での完全な攻撃は未実証
FrankenPHPmod_php と同じく後片付けを必ず実行するため、アプリケーションに依存しない攻撃を受ける可能性が高い(ソースの解析による評価)
LiteSpeed(LSAPI)FPM と同じ型。アプリケーションに依存した攻撃は可能性が高いが未検証

修正版では、OOM のときにその場で処理を打ち切るのをやめ、安全な地点で止める方式に変わりました。あわせて、より高い第2の上限(memory_hard_limit_percent)を超えるとプロセスを終了させる仕組みが入っています。

CVE-2026-109619 - RCE via stale global state

GHSA-6wmf-4rv5-p3rp の内容を要約します。

  • 仕組み: リクエストが使っていた内部の状態が、メモリを解放した後もワーカーに残ってしまいます。同じワーカーが次のリクエストを処理するとき、通常の初期化より前にその古い状態を使うと、解放済みのメモリを使う(use-after-free)ことになります。
  • 攻撃には、状態を残すリクエストと、それを使うリクエストの2つが必要です。同じワーカーに届く必要があるので、何度も試すことになります。
  • 確認されている経路:
    • PHP 8.5 の fatal_error_backtraces(致命的エラーのときにバックトレースを残す機能)。mod_php での RCE はこの経路で確認されています。
    • session upload progress(アップロードの進み具合をセッションに記録する機能。既定で有効で、アプリが session_start() を呼ばなくても動く)。mod_php と PHP-FPM の両方で RCE を確認済みです。
  • 早い段階で古い状態を使ってしまう処理: mod_php では .htaccess や Apache の php_value / php_flag / php_admin_* の設定が、リクエストの初期化より前に適用されます。PHP-FPM では、nginx や Apache の mod_proxy_fcgi から PHP_VALUE / PHP_ADMIN_VALUE を送っていて、それが警告などを出す場合に影響を受けます。
  • 認証: 不要。影響は「認証なしのヒープの use-after-free、メモリの漏えい、リモートコード実行」です。

危険度

項目CVE-2026-109618CVE-2026-109619
CVSS v4.0(php.net が採点)9.29.2
GitHub の severityCriticalCritical
NVD の CVSS v3.19.88.1
認証不要不要
CISA KEV(悪用が確認された脆弱性のカタログ)未掲載(10月27日時点)未掲載(10月27日時点)

CVSS v4.0 のベクターは2件とも AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N です。ネットワーク越しに認証なしで攻撃でき、成功すれば機密性・完全性・可用性のすべてに大きな影響がある一方、攻撃の難しさ(AC:H)と前提条件(AT:P)が付いているので、10.0 にはなっていません。

悪用の状況は次のとおりです。

  • 攻撃コード(PoC)は公開後すぐに GitHub などに多数出回りました。中には偽物もあり、注意が呼びかけられています。
  • Cloudflare は、公開前に情報が漏れていた期間に、顧客を狙った攻撃の通信を観測したと書いています(Cloudflare)。
  • JPCERT/CC も「実証コードが多数公開」「悪用を試みる通信を観測したとの報告も相次いで」いるとしています(JPCERT/CC)。
  • 攻撃が成功して侵害された事例は、この記事を書いた時点では一次情報で確認できていません。

攻撃を成功させるには、サーバーのバイナリやメモリの配置を知る必要があるなどの難しさがあります。ただ、PoC が出回り、スキャンが始まっている以上、「難しいから後回し」にはできない状況です。

影響を受けるバージョンと修正版

ブランチ影響を受ける版修正版
8.58.5.12 より前8.5.12
8.48.4.27 より前8.4.27
8.38.3.36 より前8.3.36
8.28.2.35 より前8.2.35
8.6(開発版)RC3 以前8.6.0 RC4
8.1 以前影響を受ける可能性あり正式な修正版なし(7.4 / 8.0 / 8.1 向けの最小限のソースパッチのみ)

php.net と GitHub のアドバイザリが対象として挙げているのは 8.2 以降です。一方、NVD は CVE-2026-109618 を 7.3.0 以降、CVE-2026-109619 を 5.4.0 以降としていて、古い版も影響を受けると考えた方が安全です。php.net は 8.1 以前について、深刻度を踏まえて 7.4 / 8.0 / 8.1 向けの最小限のソースパッチを用意しましたが、正式なリリースは出していません。

構成ごとの対応方法

どの構成でも、やることは「修正版に更新する」と「PHP のプロセスを再起動する」の2つです。違うのは、更新の方法と確認の仕方です。

Apache + mod_php

最も危険度が高い構成です。php.net は「リスクは mod_php が最も高い」としていて、2件ともアプリケーションのコードが動く前に悪用できます。最優先で更新してください。

Ubuntu / Debian の例(PHP 8.3 の場合)
sudo apt update
sudo apt install --only-upgrade 'php8.3*' libapache2-mod-php8.3
sudo systemctl restart apache2

あわせて、.htaccess や Apache の設定にある php_value / php_flag で、使われていない・非推奨の設定が警告を出していないかを確認します。CVE-2026-109619 の早い段階の利用につながるためです。この機会に、PHP-FPM への移行も検討する価値があります。

nginx / Apache + PHP-FPM

mod_php よりは条件が厳しいものの、CVE-2026-109619 は session upload progress の経路で RCE が確認されています。更新が必要です。

Ubuntu / Debian の例(PHP 8.3 の場合)
sudo apt update
sudo apt install --only-upgrade 'php8.3*'
sudo systemctl restart php8.3-fpm

nginx から PHP_VALUE / PHP_ADMIN_VALUE を渡しているかどうかも確認します。渡している設定が警告を出すと、CVE-2026-109619 の早い段階の利用につながります。

grep -rn "PHP_VALUE\|PHP_ADMIN_VALUE" /etc/nginx/

RHEL / AlmaLinux / Rocky Linux

Red Hat は RHEL 8 / 9 / 10 向けにエラータを出しています。RHEL のパッケージは PHP のバージョン番号が変わらずに修正が入るので(例: RHEL 9 の標準の PHP は php-8.0.30-8.el9_8.1 で修正済み)、変更履歴で確認します。AppStream のモジュールのストリームによっては、まだ修正が出ていないものもあります(10月27日時点で、RHEL 9 の php:8.4 は CVE-2026-109619 が未修正)。Red Hat の CVE のページで自分のストリームを確認してください。

sudo dnf upgrade 'php*'
rpm -q --changelog php-common | grep -E "CVE-2026-10961[89]"
sudo systemctl restart php-fpm   # mod_php なら httpd

Remi のリポジトリを使っている場合は、10月22日に 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 が出ています(Remi)。

Docker(公式の php イメージ)

公式イメージは10月21日のうちに修正版のタグが出ています。イメージを取り直すだけでは直りません。自分のイメージを作り直して、コンテナを入れ替えます。

docker pull php:8.5-apache          # 使っているタグに合わせる
docker build --pull -t my-app .     # FROM のイメージを取り直して作り直す
docker run --rm my-app php -v       # PHP 8.5.12 以降になっていること

FROM php:8.5.11-apache のようにパッチ番号まで固定している場合は、Dockerfile の書き換えが必要です。

FrankenPHP

FrankenPHP 1.13.2 が、修正版の PHP でビルドしたセキュリティリリースです(FrankenPHP のリリース)。mod_php と同じく、アプリケーションに依存しない攻撃を受ける可能性が高いとされているので、早めに更新します。

レンタルサーバー・マネージドサービス

コントロールパネルで PHP のバージョンを選ぶ共用サーバーでは、PHP の更新は事業者の作業です。たとえばさくらインターネットは、コントロールパネルで選べる PHP はすべて対応済みで、利用者の作業は不要としています(自分でインストールした PHP は対象外。さくらインターネット)。

使っている事業者の告知を確認し、あわせて次の2つを見ておきます。

  • サポートが終わった PHP(8.1 以前)を選んでいないか。事業者によってはバックポートで対応していますが、早めにサポート中の版へ切り替えます。
  • WAF の設定。Cloudflare や AWS WAF は、この脆弱性向けのルールを追加しています(Cloudflare は WAF を使っているすべてのプランで自動で有効。無料プランも含む)。WAF は攻撃の一部を止める補助で、更新の代わりにはなりません。

Windows

windows.php.net から修正版を入れ直します。10月26日には、同梱のライブラリ Brotli の脆弱性(CVE-2026-111497)を直した 8.5.12-1 などのビルドが出ているので、これから入れるならそちらを使います。

8.1 以前を使っている場合

PHP プロジェクトからの正式な修正版のリリースはありません(7.4 / 8.0 / 8.1 向けに最小限のソースパッチが公開されているだけです)。選択肢は次のとおりです。

  • OS のサポートを使う: Ubuntu は 14.04〜20.04 向けの修正を Ubuntu Pro(ESM)で提供しています(USN-8948-2)。Debian の LTS、RHEL / AlmaLinux のエラータも確認します。
  • Ondřej Surý のリポジトリ(ppa:ondrej/php など)では、5.6〜8.1 にも更新が届いたという利用者の報告があります(deb.sury.org の issue)。
  • 根本的には、サポート中の 8.4 / 8.5 へ上げる。8.2 も2026年12月31日でサポートが終わります。バージョンごとの違いとサポート期限は「PHP の最新バージョンは 8.5 - バージョン履歴と各版の変更点・サポート期限」にまとめています。

すぐに更新できないときの緩和策

php.net は「緩和策は特定の攻撃経路への露出を減らすだけで、安全にはならない」と明記しています。更新までのつなぎとして使ってください。

CVE-2026-109619 向け

php.ini に書く場合
; アップロードの進み具合をセッションに記録する機能を止める
session.upload_progress.enabled = 0
 
; PHP 8.5 のみ。致命的エラーのバックトレースを残さない
fatal_error_backtraces = 0
PHP-FPM の pool に書く場合(例: /etc/php/8.3/fpm/pool.d/www.conf)
php_admin_flag[session.upload_progress.enabled] = off
; PHP 8.5 のみ
php_admin_flag[fatal_error_backtraces] = off
  • pool の設定ファイルには php.ini の書き方(session.upload_progress.enabled = 0)をそのまま書けません。書くと PHP-FPM が起動しなくなるので、php_admin_flag[...] の形にします。
  • 設定したら、すべてのワーカーを再起動します。PHP-FPM なら、再起動の前に sudo php-fpm8.3 -t で設定を検査しておくと安全です(コマンド名は版や OS で変わります)。
  • ini_set() や FPM の .user.ini では効きません。php.ini、FPM の pool、リクエストの解析より前に効くサーバーの設定で入れます。
  • session upload progress は、アップロードの進み具合のバーを出すための機能です。使っていないなら、GitHub のアドバイザリは更新した後も無効のままにしておく方が賢明としています。
  • .htaccess や PHP_VALUE で、リクエストごとに適用される無効な設定・非推奨の設定を消します。error_reporting や display_errors、@ で警告を隠しても効果はありません。

CVE-2026-109618 向け

php.ini(ファイルのアップロードを使わないアプリの場合)
post_max_size = 8M
upload_max_filesize = 2M
PHP-FPM の pool の設定
; アプリから上書きできない形でメモリの上限をなくす
php_admin_value[memory_limit] = -1
  • post_max_size は POST 全体の上限、upload_max_filesize はファイル1つの上限です。php.net は、アップロードを使わないなら post_max_size = 8M、使うなら 32M を目安に挙げています。アップロードを使う場合は、受け付けたいファイルの大きさに合わせて upload_max_filesize を post_max_size より小さく設定し、後述の Web サーバーの上限もそろえます。
  • memory_limit=-1 は、攻撃者が狙って起こせるメモリ不足をなくすための設定です。アプリケーションやディレクトリの設定で有限の値に戻されていないかも確認します。
  • メモリの上限がなくなるので、暴走したプロセスがサーバーのメモリを使い切るおそれがあります。php.net は、コンテナや cgroup のメモリ上限を「可用性の境界」として使うことを勧めています(できれば該当のワーカーだけを止める設定で)。RLIMIT_AS や RLIMIT_DATA での代用は、脆弱な状態を起こしてしまうので使ってはいけません。
  • Web サーバーやプロキシの側でも、リクエストの大きさ、入力の項目数、multipart のパート数、ヘッダー数、ネストの深さを制限することが勧められています。次の例は、アップロードを使わないアプリでリクエストの本文を 8MB までに制限するものです。
Apache の例(VirtualHost などに書く)
LimitRequestBody 8388608
nginx の例(server や location に書く)
client_max_body_size 8m;
設定を検査してから反映する
sudo apachectl configtest && sudo systemctl reload apache2   # Apache(RHEL 系はサービス名が httpd)
sudo nginx -t && sudo systemctl reload nginx                 # nginx

PHP-FPM だけを再起動しても、nginx や Apache の設定は反映されません。ファイルのアップロードをまったく使わないアプリケーションなら、GitHub のアドバイザリは multipart のリクエストをフロントエンドで止めることも挙げています。

更新できたかを確かめる

  1. インストールされているパッケージの版を確かめる(OS のパッケージの場合。php -v の番号が変わらないことがあるため)。Ubuntu / Debian は、入っている版を各ディストリビューションの修正版(下の表やアドバイザリ)と比べます。RHEL 系は、インストール済みのパッケージの変更履歴で CVE 番号を探せます。
# Ubuntu / Debian: インストール済みの版を出し、アドバイザリの修正版と比べる
dpkg-query -W 'php8.3*'
# RHEL / AlmaLinux / Rocky: インストール済みのパッケージの変更履歴から探す
rpm -q --changelog php-common | grep -E "CVE-2026-10961[89]"

apt changelog は、インストール済みの版ではなく、これから入る候補の版の変更履歴を出すことがあります。更新前に実行すると、修正済みに見えてしまうので注意してください。

  1. Web で実際に動いている PHP を確認する。CLI の php と、Apache や FPM が使っている PHP が別のことがあります。管理者だけが見られる場所で phpinfo() を出し、確認したらすぐに消します。
  2. 古いワーカーが残っていないか。Apache、PHP-FPM、FrankenPHP、LiteSpeed のほか、Laravel Octane や RoadRunner、Swoole のような常駐型の実行環境も、プロセスを入れ替えるまで古い PHP のままです。

Ubuntu の修正済みパッケージの例(USN-8948-1):

リリースパッケージ修正版
24.04 LTSphp8.38.3.6-0ubuntu0.24.04.13
22.04 LTSphp8.18.1.2-1ubuntu2.28

Debian は bookworm が php8.2 8.2.35-1~deb12u1(DLA-4848-1)、trixie が php8.4 8.4.27-1~deb13u1(DSA-6574-1)です(Debian セキュリティトラッカー)。

10月23日・26日の追加情報

  • 10月23日: php.net は、次の通常リリースまで session.upload_progress.enabled=0 にしておくことを勧める追加情報を出しました(php.net)。session.serialize_handler を php_binary か php_serialize に設定したうえで、実行時に ini_set() で php に切り替えてから session_start() を呼ぶ、という珍しい組み合わせでだけ起こる問題(CVE-2026-115560)です。上の緩和策ですでに無効にしていれば、追加の作業はいりません。
  • 10月26日: Windows 版のビルドが 8.5.12-1 / 8.4.27-1 / 8.3.36-1 / 8.2.35-1 に更新されました(php.net)。同梱の Brotli を 1.2.1 にして、CVE-2026-111497(展開処理の範囲外書き込み)を直したものです。cURL 拡張で HTTP レスポンスの自動展開を有効にしている場合に関係します。PHP 本体のバージョンは変わりません。

まとめ

  • PHP2Shell は、PHP 本体の2件の脆弱性 CVE-2026-109618(メモリ不足を使った状態の破壊)と CVE-2026-109619(解放済みの状態の再利用)の通称。どちらも認証なしの RCE につながり、CVSS v4.0 は 9.2
  • mod_php が最も危険。アプリケーションのコードが動く前に悪用できる。PHP-FPM も CVE-2026-109619 で RCE が確認されている
  • 対応は 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 以降への更新と、全ワーカーの再起動。OS のパッケージは番号が変わらないことがあるので、変更履歴で CVE 番号を確かめる
  • すぐに更新できないなら session.upload_progress.enabled=0、fatal_error_backtraces=0(8.5)、memory_limit=-1 と入力の制限でつなぐ。ただし緩和策だけでは安全にならない
  • 8.1 以前は正式な修正版のリリースがない。サポート中の版へ上げる計画を立てる

WordPress のサイトなら、PHP の更新とあわせて「WordPress のセキュリティ対策」の内容も見直しておくと安心です。

参考資料

WordPress セキュリティ対策の基本と実践 - 公式ハンドブックと脆弱性統計から優先順位を決める

WordPress セキュリティ対策の基本と実践 - 公式ハンドブックと脆弱性統計から優先順位を決める

約33分

WordPress サイトを守るための対策を、公式の Advanced Administration Handbook と Patchstack・Wordfence の脆弱性統計をもとに優先順位をつけて整理します。2025年に見つかった脆弱性の91%はプラグイン、悪用までの中央値は5時間という現実から、更新と自動更新の設定、プラグインの選び方と減らし方、2要素認証とレート制限によるログイン保護、wp-config.php の定数とファイル権限、WP-CLI のチェックサム検証による改ざん検知、バックアップと改ざんされたときの手順、そして効果が限定的な対策まで、設定例とチェックリスト付きでまとめます。

Adobe Commerce / Magento CVE-2026-75650 (StyleSmuggler) - テンプレート署名の判定ミスが招いた未認証RCEと、3日間のゼロデイ悪用

Adobe Commerce / Magento CVE-2026-75650 (StyleSmuggler) - テンプレート署名の判定ミスが招いた未認証RCEと、3日間のゼロデイ悪用

約66分

Adobe Commerce / Magento Open SourceのCVE-2026-75650(通称StyleSmuggler、CVSS 10.0)を、Adobe APSB26-146、ホットフィックスVULN-39341の実diff、CISA KEV、Sansecの観測で整理します。テンプレートの署名判定がなぜ攻撃者入力を信用したのか、var/report汚染から支払い失敗メールの描画でPHPが動く二段階、Rust製バックドア、ホットフィックス適用と鍵ローテーションまで追います。

Citrix NetScalerの未認証RCE CVE-2026-8452 - DoSと評価された脆弱性が2か月後にKEV入りするまで

Citrix NetScalerの未認証RCE CVE-2026-8452 - DoSと評価された脆弱性が2か月後にKEV入りするまで

約43分

2026年6月30日にCitrixがDoSとして公表・修正したNetScaler ADC / Gatewayの脆弱性CVE-2026-8452は、8月14日のwatchTowr Labsの解析で未認証RCEに到達できることが示され、8月26日にCISA KEVへ追加されました。SAML署名の正規化処理で起きるヒープオーバーフローの中身、CVSSが8.8と9.8に割れる理由、影響ビルドの確認手順、パッチ済みでも必要な侵害調査と事後対応を一次情報から整理します。

楽天市場のおすすめPR / 楽天アフィリエイト