本文へ移動
相談する

RELEASE

PHP2Shellから考える、脆弱性の本質

PHPの重大な脆弱性は、なぜアプリの認証より前に影響を及ぼし得るのか。メモリと状態の寿命、共通基盤への依存、AI時代の修正対応から考えます。

問題は、アプリケーションより手前にある。

2026年10月21日、PHPは認証なしの遠隔コード実行につながり得る2件の脆弱性を公表しました。CVE-2026-109618とCVE-2026-109619、通称PHP2Shellです。この記事は10月22日時点の公開情報に基づきます。攻撃が成立すると、サーバー上で第三者のコードが実行されるおそれがあります。

01 / THE REQUEST BOUNDARY

認証が始まる前に、PHPの内部処理が動く。

01 / 外部からの入力

HTTP REQUEST

リクエストを送る

アプリへのログイン前でも
サーバーへ入力は届く

SERVER / サーバー内で進む処理

02 / アプリ実行前

PHP実行基盤

  1. 入力データの解析
  2. 内部状態の準備

今回の問題が起きる層

03 / アプリの実行

認証・業務処理

ログイン判定業務データへのアクセス

ここでの認証では、
その前の層を保護できない

mod_phpで実証された経路では、PHP内部で問題が起きた後にアプリの認証を置いても防げません。修正すべき対象は、アプリを動かすPHP本体です。

PHPはアプリケーションのコードを動かす実行基盤でもあります。PHP公式は、Apacheのmod_phpでアプリのコードが動く前に攻撃を引き起こせる実証があり、特にリスクが高いと説明しています。PHP-FPMなどのWeb実行環境も対象として挙げており、mod_php以外なら安全という意味ではありません。

このため、アプリのログイン画面を設けることと、実行基盤の脆弱性を修正することは別の対策です。アプリだけを見ていても、処理がそこへ到達する前の問題は見落としてしまいます。

PHP公式のセキュリティ勧告を読む

初期化の途中で止まり、不完全な状態が使われる。

CVE-2026-109618は、メモリ不足時の処理に関わる問題です。PHPがリクエスト用の内部データを準備している途中でメモリ確保に失敗すると、処理が中断され、データが不完全な状態で残る場合があります。

02 / CVE-2026-109618

初期化は止まった。終了処理は、その状態を使ってしまう。

準備済み未完成

正常な処理使える状態を保つ

  1. 01 / 初期化

    準備済み準備中準備中

    内部データを準備する

  2. 02 / 完了

    準備済み準備済み準備済み

    必要な状態がそろう

  3. 03 / 終了処理

    有効な状態を扱う

    整合した状態で後始末する

脆弱な処理中断した状態を使う

  1. 01 / 初期化

    準備済み準備中準備中

    未完成でも、一時的に参照できる

  2. 02 / メモリ不足で中断

    準備済み未完成未完成

    初期化が途中で終わる

  3. 03 / 終了処理

    未完成の状態を参照

    不正な状態を読み、処理を分岐させる

守るべき境界処理を止めた後も、不完全な状態を終了処理に渡さない。
メモリ不足が発端でも、危険なのはその後の状態の扱いです。図のマスは内部データの準備状況を示します。

その後の終了処理が、そのデータを使えるものとして読み取ったり、処理を分岐させたりします。「エラーが起きたので止まった」だけでは安全とは限りません。止まった後の後始末まで含めて、状態の整合性が必要になります。

初期化とメモリ不足についての公式勧告

終わったリクエストの状態が、次の処理に残る。

CVE-2026-109619では、ワーカーが保持する内部状態が、すでに終わったリクエストのメモリを指したまま残ります。本来は、そのリクエストのメモリを解放する前に、参照する状態をリセットする必要があります。

03 / CVE-2026-109619

データの寿命が終わっても、参照だけが次へ残る。

同じワーカーが、複数のリクエストを処理する

  1. 01 / リクエストAの処理中

    ワーカーが持つ状態データAへの参照
    データAリクエストAのメモリ

    参照先のデータが存在する

  2. 02 / リクエストAの終了後

    リセットされず残るデータAへの参照
    解放済みメモリデータAの寿命は終了

    メモリを解放しても、古い参照は残る

  3. 03 / リクエストBの開始時

    初期化より前の処理が利用データAへの参照
    解放済みメモリ有効なデータとして扱う

    通常の初期化で置き換わる前に参照する

USE-AFTER-FREE片付けたはずのデータを、次のリクエストが使ってしまう。
本来必要な順序参照をリセットメモリを解放
段階をつなぐ矢印は時間の進行、状態からメモリへ向かう矢印は参照です。ワーカーに残る状態と、リクエストごとに解放されるメモリの寿命が食い違っています。

ところが、次のリクエストの通常の初期化より先に走る処理が、その古い状態へアクセスします。すでに解放したメモリを使う「use-after-free」です。一つのワーカーが複数のリクエストを扱う仕組みで、リクエストごとの寿命と、ワーカー側に残る状態の寿命が食い違いました。

残存する状態についての公式勧告

本質は、状態の境界を異常時にも守れるか。

この2件を設計の観点から見ると、共通するのは「いつから使える状態なのか」「いつまで参照してよいのか」という境界の崩れです。これは、公開された原因から私たちが重視する設計上の論点です。

セキュリティの検証には、正常に動く経路に加え、初期化の失敗、途中の中断、後始末、次の処理への再利用が含まれます。何が起きても、未完成の状態を完成済みとして使わず、寿命を終えた状態を次へ持ち越さない。その保証が重要です。

AIが見つけても、防御は修正が届いて初めて進む。

OpenAIは、CalifがGPT-5.6 Solを用いて重大な欠陥を発見し、Wizも独立に両方の脆弱性を発見・報告したと公表しています。修正とリリースはPHPのメンテナーが主導しました。AIだけがすべてを自動で解決した、という出来事ではありません。

ここから得られる教訓は、発見する能力と、利用者の環境へ修正を届ける能力の両方が必要だということです。依存する基盤と更新責任者が分かり、修正版を検証・展開し、実際の稼働状態まで確かめられる体制が、防御の速度を左右します。

発見と修正対応の経緯についてのOpenAIの発表

利用企業は、PHP本体と提供元の修正を確認する。

公表時の修正版はPHP 8.2.35、8.3.36、8.4.27、8.5.12です。修正対象はPHP本体にあるため、CMSやフレームワークだけの更新で対応が終わるとは限りません。ディストリビューションやホスティング提供元が修正を取り込む場合は、提供元の勧告で適用状況を確認します。

PHP 8.1以前は、PHPプロジェクトによる通常のサポートが終了しています。古い環境も、ベンダーによる修正の提供状況を確認するか、サポート対象のバージョンへ移行する必要があります。

PHP公式は、設定変更による暫定策ではすべての経路を安全にできず、修正の適用が必要だとしています。使っている基盤と担当者を把握し、修正の適用、必要な再起動、修正済みのプロセスが動いていることの確認までを一つの対応として進めます。

IPAの注意喚起と修正バージョンを確認する

共通基盤への依存を、事業のリスクとして捉える。

ENISAなどの共同声明は、PHPを直接使っているように見えない製品でも、内部でPHPに依存している場合があると指摘しています。インターネットへ公開しているシステムを優先して確認し、すぐに修正できない場合は、修正までの間に公開ネットワークから隔離することも検討するよう勧めています。

一つの共通部品への依存が、多くのサービスに同時に対応を求める。今回の問題が示しているのは、コードの品質だけでなく、何に依存し、誰が保守し、どのくらいで更新できるかまでが、事業の継続性に関わるということです。

ENISAなどの共同声明を読む