2026年10月21日、PHP プロジェクトは緊急のセキュリティ更新を公開しました。修正されたのは、ログインしていない第三者が、外部から Web サーバー上でプログラムを実行できてしまうおそれのある、重大な脆弱性 2 件です。海外のセキュリティ各社が「PHP2Shell」という通称で紹介したことで、国内でも大きな話題になりました。

「PHP を使っているが、自分のサイトは大丈夫なのか」「何をすればよいのか」と不安になった方も多いでしょう。この記事では、専門用語をできるだけ日常の言葉に置き換えながら、どこに問題があり、どれほど危険で、何をすればよいのかを順番に説明します。確認日は 2026年10月26日です。

脆弱性

CVE-2026-109618 と CVE-2026-109619 の 2 件です。

危険度

どちらも CVSS v4.0 で 9.2 の「緊急(Critical)」です。

直す方法

PHP を 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 以降へ更新します。

急ぐ理由

PHP は、更新だけが完全な対策だと明言しています。

「たかが PHP の不具合」では済まない理由

最初に、なぜこの脆弱性が大きく扱われているのかを整理します。理由は 4 つあります。

理由 1: ログインなしで、外から攻撃できる

PHP プロジェクトの告知によれば、どちらの脆弱性も「認証なし」の遠隔コード実行(RCE)につながります。合言葉もアカウントも要らず、インターネットから届く通信だけで攻撃が成り立つ可能性があるということです。

理由 2: サイトのプログラムが動く前に、攻撃が始まりうる

とくに Apache の mod_php という方式では、サイトのプログラムが一行も動く前に、攻撃が成立する実証があると告知されています。自分のサイトのコードをどれだけ丁寧に書いていても、防げません。問題が PHP 本体にあるためです。

理由 3: 対象がとても広い

告知では、PHP-FPM、Apache の mod_php、php-cgi、FrankenPHP、LiteSpeed など、Web の要求を受ける PHP の環境は、すべてが対象になりうるとされています。WordPress、EC-CUBE、Laravel など、PHP で動くものは土台が同じです。ただし、問題は PHP 本体にあるため、これらのアプリケーションを最新にしても、PHP 自体を更新しなければ解消しません。

理由 4: すでに更新を受けられない古い版がある

PHP 8.1 以前は、PHP プロジェクトからの更新が終了しています。古い版のまま運用していると、公式の修正版が存在しません。

なお、セキュリティ会社の中には、インターネットに公開されていて影響を受けうる PHP が 2,260 万件を超えると発表したところがあります。この数字は「攻撃を受けうる状態の数」を推計したもので、実際に侵入された件数ではありません。悪用の状況については、本記事の確認日時点で、情報源によって見解が分かれています。悪用の有無が確定していないことは、安全の根拠にはなりません。

先に結論: やることは「更新」と「再起動」

不安をあおるだけでは役に立たないので、先に結論を書きます。

  1. PHP のバージョンを確認します。
  2. 修正版(8.5.12、8.4.27、8.3.36、8.2.35 以降)へ更新します。
  3. 更新したら、PHP を動かしているプロセスを再起動(または再デプロイ)します。
  4. すぐ更新できない場合は、暫定対処を入れて、更新までの危険を下げます。

この流れを頭に置いて、以降を読み進めてください。

背景: PHP が 1 つの要求をさばく仕組み

脆弱性を理解するために、PHP が Web の要求をさばく流れを簡単に説明します。専門的な話ですが、身近なたとえで十分に理解できます。

PHP は、受付窓口のような役割です。利用者が Web ページを開くたびに、窓口(PHP の作業員)が次の順で仕事をします。

  1. 準備: 窓口を整え、その要求用のメモ帳を用意します(初期化)。
  2. 処理: 要求の内容を読み、サイトのプログラムを実行します。
  3. 後片付け: メモ帳を片付け、窓口を空にします(終了処理)。

この作業員は、1 件ごとに入れ替わるのではなく、次の要求でも同じ人が使い回されるのが一般的です。作業員を毎回作り直すより、使い回すほうが速いからです。この使い回しが、後で説明する問題の鍵になります。

作業員の置き方にも種類がある

作業員の置き方(SAPI と呼びます)には種類があります。

方式 概要 今回のリスク(PHP 告知・アドバイザリ)
mod_php Apache の中に PHP を組み込む 最も高い。実証済み
PHP-FPM PHP を別プロセスとして動かし、Nginx などと連携 影響を受けうる。完全な攻撃は未実証(109618)
FrankenPHP・LSAPI など 別の実行方式 影響を受けうるが、検証は限定的

ここで大切なのは、「PHP-FPM だから安心」とは言えないことです。アドバイザリは、PHP-FPM でも条件が揃えば成立する経路があると述べています。

問題の箇所 1: メモリ不足の「後始末」を誤る(CVE-2026-109618)

1 つ目の脆弱性は、メモリ不足のときの処理にあります。

何が起きるか

PHP は、メモリが足りなくなると、longjmp() という仕組みで、処理を一気に中断します。たとえるなら、作業の途中で「緊急停止ボタン」を押し、いまやっていることを放り出して、後片付けの場面へ飛ぶようなものです。

ところが、準備の途中で緊急停止が起きると、メモ帳が半分しか整っていない状態になります。それでも後片付けの処理は、「メモ帳は整っている」と思い込んで進めてしまいます。壊れた内容を正しいものとして扱うため、メモリの安全が崩れます。アドバイザリでは、これを「解放後のメモリの利用(Use After Free)」の種類と分類しています。

攻撃者が意図的に起こせるのか

アドバイザリによると、ファイルのアップロードなどに使う「マルチパート」形式の読み取りに、細工が可能な箇所があります。たとえば、1 つの部品に付けられるヘッダーの数に上限がないことや、中身が空のファイル欄の扱いです。これらを使うと、見かけ上の制限内の通信でも、メモリ不足に追い込めるとされています。

つまり、特別な権限がなくても、細工した通信を送るだけで、窓口を意図的に緊急停止させられる可能性があるのです。

問題の箇所 2: 前の要求の「残りもの」を使ってしまう(CVE-2026-109619)

2 つ目の脆弱性は、前の要求の状態が残る問題です。

何が起きるか

先ほどのたとえでいえば、前の客のメモ帳を片付けきれないまま、次の客の対応を始めてしまう状況です。アドバイザリでは、エラーやセッション、オブジェクトといった要求ごとの状態が、要求が終わったあとも残ることがあると説明しています。

さらに、一部の処理は、通常の準備が終わるより前に動きます。その処理が、すでに片付けられたはずの古い情報を読んでしまうと、解放済みのメモリを使うことになり、情報の漏えいや、プログラムの実行につながります。

clientserver

要求 A: 大きすぎる入力でメモリ不足(作業員 1)
緊急停止のため、後片付けが済まないまま終わります
要求 B: 同じ作業員 1 に届く
準備より前の処理が、前の要求の古い情報を読んでしまいます
解放済みのメモリを使い、異常な動作が起きます

この図のとおり、攻撃の成立には、悪意ある要求と、次の要求が同じ作業員に届くことが条件になります。

確認された具体的な経路

アドバイザリは、実際に確認された経路を 2 つ挙げています。

  • PHP 8.5 の「致命的エラーのバックトレース」機能(fatal_error_backtraces)が有効なとき。最も強い例で、mod_php に対する遠隔コード実行が確認されています。
  • セッションのアップロード進捗機能(session.upload_progress)。初期設定で有効で、入力の処理中にメモリ不足が起きると、セッションの状態が古いまま残りえます。mod_php と PHP-FPM の両方で検証されています。

さらに、Apache の .htaccess やディレクトリ単位の php_value 設定は、PHP の準備より前に適用されるため、古い情報を読む処理の入口になりうるとも書かれています。PHP-FPM では、前段のサーバーが PHP_VALUE などの値を送る構成の場合に限り、同様の入口ができます。

影響の大きさ: CVSS 9.2 をどう読むか

2 件とも、深刻度を表す CVSS v4.0 で 9.2(Critical) と評価されています。数値の読み方を、初心者向けに整理します。

項目 値 意味
攻撃元(AV) ネットワーク インターネット越しに攻撃できる
攻撃の複雑さ(AC) 高 成功させるのに工夫が要る
攻撃の前提条件(AT) あり 特定の条件が整う必要がある
必要な権限(PR) 不要 ログインなしで攻撃できる
利用者の操作(UI) 不要 誰かがクリックする必要もない
機密性・完全性・可用性への影響 すべて高 情報の盗難、改ざん、停止のすべてが起こりうる

「攻撃の複雑さが高い」と聞くと、安心したくなるかもしれません。しかし、認証もクリックも不要で、影響が最大であるため、全体としては 9.2 という高い評価になっています。複雑さが高くても、攻撃が自動化されれば、実際の危険は小さくなりません。

実行されるのは「Web サーバーの権限」

アドバイザリによると、攻撃が成功したときに実行されるプログラムは、Web サーバーの作業用アカウントの権限で動きます。これは、サイトのファイルやデータベースの接続情報など、そのアカウントが触れるものすべてが危険にさらされることを意味します。設定ファイルに保存された接続用のパスワードも、読み取られる可能性があります。そのため、侵入が疑われる場合は、パスワードなどの再設定も検討が必要です。

対応策 1: PHP を更新する(これが本命)

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 以降(8.2 系は 2026年12月31日に終了予定)

自分の PHP のバージョンを調べる

サーバーに入れる場合は、次のコマンドで確認できます。

php -v

Web 経由で動いている PHP の版は、CLI と異なることがあります。確実に調べるなら、管理者限定の場所で phpinfo() を表示するか、サーバー会社の管理画面で表示されるバージョンを確認します。調べ終わったら、phpinfo() を載せたファイルは必ず削除してください。

Docker などのコンテナを使う場合は、利用中のイメージの版を確認し、上の更新先を含むタグへ入れ替えて、再デプロイします。

ディストリビューションやサーバー会社の場合

Linux ディストリビューションが配布する PHP は、版の番号が変わらないまま、修正だけが取り込まれることがあります。PHP プロジェクトの告知でも、ディストリビューションや長期サポートの提供元には、事前にパッチが届いたとされています。番号だけで判断せず、提供元の告知で「修正済み」と書かれているかを確認してください。

レンタルサーバーなど、PHP を自分で更新できない環境では、管理画面の PHP バージョンの切り替え機能や、サーバー会社の告知で対応状況を確認してください。

更新後は「再起動」まで終えて完了

PHP を更新しても、動いているプロセスが古いままでは、修正は効きません。PHP-FPM や Apache を再起動する(コンテナなら再デプロイする)ところまでを、作業に含めてください。

対応策 2: 古い PHP を使っている場合

PHP 8.1 以前は、PHP プロジェクトからの更新が終了しています。この場合は、次のどれかを選びます。

  1. 新しい系統へ移行する。 もっとも確実な方法です。
  2. 提供元の延長サポートを使う。 ディストリビューションや長期サポートの提供元が、修正を取り込んで配布している場合があります。
  3. 自分でビルドしているなら、公開された修正を適用する。 PHP のセキュリティチームは、PHP 7.4、8.0、8.1 向けに、最小限の修正(バックポート)を公開しています。

いずれも、古い版のまま使い続けることには、これ以外にも多くの未修正の問題を抱えるリスクがあります。移行の計画を立てる機会として捉えてください。

対応策 3: すぐ更新できないときの暫定対処

事情があって、すぐには更新できない場合の手段も、PHP プロジェクトは示しています。ただし、完全な対策ではありません。更新までの時間稼ぎとして使ってください。

対象 設定 狙い
109618 memory_limit = -1 制御可能なメモリ不足を起こしにくくする
109618 post_max_size を小さくする(アップロード不要なら 8M、必要なら 32M) 大きな入力を受けにくくする
109618 upload_max_filesize を post_max_size より小さく 同上
109619 session.upload_progress.enabled = 0 確認された経路の一つを閉じる
109619(PHP 8.5 のみ) fatal_error_backtraces = 0 確認された経路の一つを閉じる

php.ini の例は、次のとおりです。

memory_limit = -1
post_max_size = 8M
upload_max_filesize = 8M
session.upload_progress.enabled = 0

PHP-FPM では、アプリケーション側から上書きされない php_admin_value を使います。

php_admin_value[memory_limit] = -1
php_admin_value[session.upload_progress.enabled] = 0

暫定対処の落とし穴

暫定対処には、見落としやすい注意点があります。

  • ini_set() や .user.ini では不十分です。 アップロード進捗の無効化は、php.ini、FPM のプール設定、サーバーの設定で行い、設定後に作業員(ワーカー)を再起動します。
  • memory_limit = -1 は、完全ではありません。 土台のメモリ確保そのものが失敗すれば、同じ経路に入りえます。
  • RLIMIT_AS や RLIMIT_DATA による制限は使わないでください。 これらは、問題の経路を引き起こすことがあると警告されています。
  • エラー表示を隠しても効果はありません。 display_errors や error_reporting、@ でエラーを隠しても、内部で起きることは変わりません。

さらにリスクを下げる手段として、Web サーバーや前段の装置で、入力の大きさ、項目の数、部品の数、ヘッダーの数を制限する方法があります。また、PHP-FPM の pm.max_requests=1 にすれば、作業員が毎回作り直されるため、「前の要求の残り」が使われる危険を減らせます。ただし、処理が遅くなる可能性があります。

もう一つの注意: CVE-2026-115560

10月23日に、PHP プロジェクトは追加の参考情報を出しました。セッションのアップロード進捗に関する別の脆弱性(CVE-2026-115560)で、PHP プロジェクトは「起こりにくい」と評価しています。

発生には、次の 3 つがすべて揃う必要があります。

  1. アプリケーションが session.serialize_handler を php_binary または php_serialize に設定しています。
  2. 実行時に ini_set() で php に切り替えてから session_start() を呼んでいます。
  3. セッションのアップロード進捗が有効になっています。

対策は、同じく session.upload_progress.enabled=0 です。すでに前述の暫定対処として入れていれば、追加の作業はありません。詳しい勧告は、次回の通常リリースで公開される予定です。

更新後に確認すること

作業が終わったら、次の点を確認しましょう。

  1. 版数: 実際にサイトを動かしている PHP が、修正版以降になっていること。
  2. 再起動: PHP-FPM、Apache、コンテナなどを再起動または再デプロイしたこと。
  3. 設定: 暫定対処を入れた場合、phpinfo() などで実際に反映されていること。確認後はそのファイルを消してください。
  4. ログ: メモリ不足や致命的エラーの記録が、更新前後で不自然に増えていない。アドバイザリは、ログを見ても、それだけでは安全の証明にならないと注意しています。

異常な兆候があれば、サイトのファイルが改ざんされていないか、見覚えのないファイルやアカウントがないかを調べ、接続用のパスワードを変更するなど、被害を広げない行動をとります。

一度きりの騒ぎにしないために

最後に、今回の件から学べる運用の考え方を挙げます。

  • 更新の通知を受け取る体制を作ります。 PHP プロジェクトは、今回、公開の前日に予告を出しました。予告を受けて、更新の準備をしておく運用が理想です。
  • サポート期間を把握します。 たとえば PHP 8.2 は 2026年12月31日に終了予定です。終了のかなり前から、次の版への移行を計画します。
  • 重要な設定は、アプリから上書きできない場所に置きます。 FPM の php_admin_value のように、管理者だけが変えられる設定にします。
  • 更新を、再起動まで含めた手順にします。 「更新した」と「反映された」は別物です。

今回の件を通じて確認しておきたいこと

要点を整理します。

  • 2026年10月21日、PHP の重大な脆弱性 2 件(CVE-2026-109618、CVE-2026-109619)の修正版が公開されました。
  • どちらも CVSS v4.0 で 9.2。ログインなしの遠隔コード実行につながりえます。
  • 問題の箇所は、メモリ不足時の後始末の誤りと、前の要求の状態が残ることです。
  • 完全な対策は、8.5.12、8.4.27、8.3.36、8.2.35 以降への更新と、再起動です。
  • 更新できない間は、暫定対処で危険を下げますが、これは時間稼ぎです。
  • 8.1 以前は、公式の更新が終了しています。移行か、提供元の延長サポートを検討します。

まずは、お使いの PHP のバージョンを確認してください。修正版になっていれば、再起動の有無を確かめて作業は完了です。まだであれば、今日のうちに更新の段取りを決めましょう。