集酒のログインとメール送信を、Google Workspace と Route 53 でどこまで賄えるか
2026-10-21 の PHP 緊急セキュリティリリース:認証なしで遠隔コード実行に至る 2 件の脆弱性
shika さんの依頼は「10/21 に修正パッチが公開された PHP の脆弱性が、どういうものだったか」です。php.net の告知では、2026-10-21(14:00 UTC、日本時間 21 日 23:00)に、サポート中の 4 系統すべてに対する修正版が出ています。直す脆弱性は 2 件で、どちらも「認証なしで、Web サーバーの PHP プロセス権限で任意のコードを実行されうる」という最も重い部類です。日付は依頼と一致しています。
先に結論
- CVE-2026-109618「メモリ不足(OOM)時の処理で内部状態が壊れる」:リクエストの処理中にメモリ上限に達すると、PHP は初期化途中のデータを残したまま処理を打ち切り、その後の後片付けがそれを正しいデータとして使ってしまう。Apache の mod_php では、アプリのコードが 1 行も動く前の「POST 本文の自動解析」の段階で攻撃が成立し、HTTP 越しの遠隔コード実行が実証済み。
- CVE-2026-109619「前のリクエストの状態が、解放後も残る」:致命的エラーやタイムアウトで中断されたリクエストの内部状態が、メモリ解放後もプロセスに残り、同じワーカーが次に処理するリクエストがそれを使ってしまう(解放済みメモリの使用)。mod_php と PHP-FPM の両方で、標準で有効な「セッションのアップロード進捗」機能を経由した遠隔コード実行が実証済み。
- 深刻度は、PHP 側(CVE の採番元)が CVSS v4.0 で 9.2(Critical)、NVD が CVSS v3.1 で 9.8(Critical)。2 件とも同じ値。
- 直すには更新するしかないと PHP 自身が書いている。設定での回避策は「特定の攻撃経路を狭めるだけで、安全にはならない」。
- 修正版: 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35。8.1 以前は公式の修正版が出ない(7.4・8.0・8.1 向けに最小限のソースパッチのブランチだけが置かれている)。
- 所見:PHP を Web で動かしている案件は全部が対象。WordPress などアプリの種類は関係なく、PHP 本体を上げるのが対応。特に mod_php 構成と、PHP 8.1 以前のまま放置されているサーバーは最優先。
どのリリースか(日付の確認)
| 日付 | php.net の告知 | 中身 |
|---|---|---|
| 2026-10-20 | Upcoming Critical PHP Security Release | 事前予告。「2026-10-21 14:00 UTC に出す」「重大な脆弱性 2 件、どちらも CVSS v4.0 9.2」。詳細はリリース時に公開とした |
| 2026-10-21 | PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 Released! | 「CVE-2026-109618、CVE-2026-109619 の 2 件を直すセキュリティリリース」。各系統の利用者に即時更新を促す |
| 2026-10-21 | Security advisory: Critical remote code execution vulnerabilities, update now | 影響範囲・更新方法・暫定の回避策をまとめた告知(下で詳しく書く) |
| 2026-10-21 | PHP 8.6.0 RC4 available for testing | 開発中の 8.6.0 のテスト版。同じ 2 件の修正を含む。「8.6.0 の以前のビルドを使っている人は更新を」 |
出典: php.net: Security advisory(2026-10-21)、php.net: Upcoming Critical PHP Security Release(2026-10-20)、php.net トップのニュース欄(いずれも 2026-10-22 08:15 JST に取得)
日付の小さなずれ:php.net のニュースは 4 系統とも 21 Oct 2026 ですが、ChangeLog の版の見出しは 22 Oct 2026 になっています。理由は書かれていません(未確認)。CVE.org の公開時刻は 2026-10-21 13:48〜13:54 UTC、NVD への登録は 2026-10-21 14:17 UTC で、告知の予定時刻とも合うため、本書では公開日を 2026-10-21 とします。
8.3.36 と 8.2.35 の ChangeLog は、この 2 件の修正(Core: Avoid state corruption via bailout)だけです。8.5.12 と 8.4.27 は通常のバグ修正もまとめて入っていますが、GHSA/CVE 番号が付いたものはこの 2 件だけでした(ChangeLog を取得して番号を抜き出して確認)。
脆弱性 1:メモリ不足時の処理で内部状態が壊れる(CVE-2026-109618)
| 項目 | 内容 |
|---|---|
| 番号 | CVE-2026-109618 / GHSA-w8hw-w9fx-j79w |
| 勧告の題 | RCE via OOM corruption |
| 場所 | PHP 本体(Zend エンジンのメモリ管理と、リクエストの開始・終了処理)。特定の拡張モジュールではない |
| 種類 | 例外的な状況の処理不備から、未初期化メモリの参照・解放済みメモリの使用に至るメモリ破壊。CWE-416(解放後の使用)、CWE-755(例外的状況の処理不備)、CWE-824(未初期化ポインタの参照)、CWE-1325(メモリ確保量の制御不備)、CWE-1419(資源の初期化不備) |
| 攻撃者ができること | 認証なしで、Web サーバーの PHP ワーカーのアカウント権限による任意コード実行(勧告で「確認済み」)。成功率はビルド・拡張・前段のサーバー・メモリ配置に左右される |
何が起きるか
PHP は、メモリ上限(memory_limit)に達するとその場で処理を打ち切ります。この打ち切りは C 言語の longjmp() で途中の処理を飛び越える方式で、確保途中・初期化途中のデータが「途中のまま」残ることがあります。その後、リクエストの後片付けがそのデータを読んだり、その値で分岐したりするため、メモリが壊れます。メモリ不足を起こしたきっかけの確保と、壊れるデータは無関係でよいのが厄介な点です。
攻撃者は「わざとメモリ不足を起こす」ことができます。勧告が挙げる方法は、multipart/form-data(ファイルアップロードのフォーム形式)の解析の性質を使うもので、Content-Length が無いリクエスト、パートごとのヘッダー数に上限が無いこと、空のファイル欄が max_file_uploads に数えられないこと、などにより、見かけ上は制限内のリクエストでメモリ上限に達するとされています。アプリ固有の重い処理でも起こせます。
実行環境(SAPI)ごとの影響
| 実行環境 | 勧告の評価 |
|---|---|
| Apache の mod_php | 最も危険。起動処理が失敗しても終了処理を呼ぶため、POST 本文の自動解析(アプリのコードより前)で発火する。標準の制限値のまま、HTTP 越しの遠隔コード実行を検証済み |
| PHP-FPM | 起動処理が失敗すると子プロセスごと終わるため、露出は小さい。ただしリクエスト処理中の後半のメモリ不足では到達しうる。FPM での完全な攻撃は実証されていない |
| FrankenPHP | 終了処理を無条件に呼ぶため、ソースの分析上は影響を受ける可能性が高い(未実証) |
| LiteSpeed(LSAPI) | FPM に近い作り。アプリ次第で攻撃できる可能性が高いが未検証 |
どう直したか
メモリ不足時の longjmp() をやめ、次の安全な地点で穏やかに止める「ソフトなメモリ不足」と、さらに高い閾値で プロセスを即終了(_exit())する「ハードなメモリ不足」の 2 段にしています。挙動の変化なので、メモリ上限ぎりぎりで動いている処理は、更新後に止まり方が変わる可能性があります(勧告からの推論。実測は未確認)。
出典: GitHub: GHSA-w8hw-w9fx-j79w(2026-10-22 08:30 JST 再取得)
補足:GC があるのに、なぜ防げないのか
この補足と次の補足は、勧告の記述ではなく一般的な仕組みからの説明です(2026-10-22 追記)。勧告には壊れる構造体の名前や攻撃の具体的な手順は書かれていません。
PHP にも GC はあります(変数の値は参照カウントで管理し、循環参照は循環回収で拾う。リクエスト中のメモリはリクエストの終わりにまとめて捨てる)。ただし GC が扱うのは「もう使われていない値を、いつ解放するか」です。今回は「解放していないのに中身が半端」「解放済みなのに参照が残っている」という状態の食い違いで、GC は書かれている情報を正しいと信じて動きます。壊れた状態を渡されると、むしろそれをたどって被害を広げる側に回ります。そもそも壊れるのは Zend エンジンの C 言語レベルの内部データで、GC の管轄外です。
食い違いのイメージ(実際のコードではなく例え):①配列を作る → ②「要素は 3 個」と件数を書き込む → ③要素を入れる場所を確保しようとして上限を超え、longjmp() で脱出 → ④後片付けが「3 個あるはず」と、設定されていないポインタを 3 回解放しにいく。
補足:内部状態の食い違いが、なぜ遠隔コード実行になるのか
前提:未初期化のメモリは空っぽではない。C で確保したばかりのメモリには、直前にそこを使っていたデータがそのまま残っています。PHP は同じリクエストの中でメモリを使い回すため、攻撃者が送った POST 本文の断片が、ちょうど使い回される場所に残っている状況を作れます。上の例えの「設定されていないポインタ」は、どこでもない値ではなく、攻撃者が仕込んだアドレスになりえます。
そこから乗っ取りまでの一般的な型は次のとおりです。
- 好きな場所を「解放」させる:後片付けが、攻撃者の仕込んだアドレスを解放します。メモリ管理の側は「そこは空いた」と記録します
- 大事なデータと重ねる:次の確保でその場所が渡され、PHP 内部の大事なデータと、攻撃者が中身を書ける文字列などが同じ場所に重なります
- 関数ポインタを書き換える:PHP の内部データには「この操作ではこの関数を呼べ」という関数のアドレスを持つものがあります。重なった場所への書き込みで、それを
system()のような関数に差し替えます - PHP が自分で呼ぶ:後片付けなどでその関数ポインタが呼ばれると、攻撃者の選んだ処理が、攻撃者の選んだ引数で実行されます。これが遠隔コード実行です
ひとことで言うと「解放したと嘘をつかせる → 空いた場所を二重に使わせる → 呼び出し先のアドレスを書き換える」です。コードを送り込む必要はなく、PHP が元々持っている関数を、間違った引数で呼ばせるだけで足ります。解放後使用(CWE-416)からコード実行に至る、よく知られた型です。
それでも「攻撃条件が複雑」と評価されている理由(推測):PHP 側の評価は AC:H(攻撃条件が複雑)・AT:P(前提条件あり)です。理由は勧告に書かれていませんが、関数のアドレスは ASLR(起動ごとのアドレスのランダム化)で毎回変わるため、知るか当てる必要があるからだと考えられます。一方、勧告が検証に使った「prefork の mod_php」は、同じ親プロセスから複製したワーカーが親と同じアドレス配置を引き継ぎます。失敗してワーカーが落ちても同じ配置で何度でもやり直せるので、総当たりが現実的になる構成です(ここも一般的な仕組みからの推測)。
出典: GitHub: GHSA-w8hw-w9fx-j79w、CVE.org レコード(API)、NVD: CVE-2026-109618(2026-10-22 08:16 JST 取得)
脆弱性 2:前のリクエストの状態が、解放後も残る(CVE-2026-109619)
| 項目 | 内容 |
|---|---|
| 番号 | CVE-2026-109619 / GHSA-6wmf-4rv5-p3rp |
| 勧告の題 | RCE via stale global state |
| 場所 | PHP 本体のグローバル状態(エラー、セッション、オブジェクト、拡張モジュールの状態)。確認済みの経路はセッション拡張(アップロード進捗)と、PHP 8.5 の致命的エラー時のバックトレース |
| 種類 | 解放済みメモリの使用(ヒープの use-after-free)。CWE は脆弱性 1 と同じ 5 つ |
| 攻撃者ができること | 認証なしで、ヒープの解放後使用・メモリの内容の漏えい・ワーカー権限での遠隔コード実行 |
何が起きるか
PHP-FPM や mod_php のワーカーは、1 つのプロセスで多数のリクエストを順に処理します。PHP には「今のリクエストのメモリを指しているグローバルな状態」があり、本来はリクエストのメモリを解放する前にリセットされます。ところが、
- 仕込み役のリクエスト:致命的エラー(メモリ不足や
Maximum execution time exceededを含む)でリセット前に中断される、または終了処理中に警告が出て状態が詰め直される → 解放済みメモリを指す状態がプロセスに残る - 発火役のリクエスト:同じワーカーが次に処理するリクエストで、通常の初期化がリセットするより前にその状態が使われる → 解放済みメモリの使用
同じワーカーに当たる必要があるため、ワーカー数が多い・定期的に入れ替わる構成では成功率は下がりますが、無くなりはしないと勧告は書いています。
確認された「発火役」の経路
- セッションのアップロード進捗(
session.upload_progress):標準で有効。通常のセッション初期化より前に、残ったセッション状態に触れる。mod_php と PHP-FPM の両方で遠隔コード実行を検証済み - リクエスト初期化前の INI 設定の警告:リクエストごとに適用される設定(mod_php のディレクトリ単位の
php_value・.htaccess、FPM なら前段から送るPHP_VALUE)が警告・非推奨通知を出すと発火する。error_reportingを下げても、@を付けても、表示やログを切っても防げない - PHP 8.5 の
fatal_error_backtraces:最も強く確認された経路として、mod_php での遠隔コード実行が示されている
実行環境別では、mod_php が確認済み、PHP-FPM は前段から PHP_VALUE を送る構成で条件付き(プール設定や .user.ini は同じ早さで効かない)、セッション経路は FPM でも検証済み、LiteSpeed は条件付きの候補、FrankenPHP は標準構成では早期の発火経路が見つかっていない、とされています。遠隔コード実行にはヒープの配置を狙って整える必要があります。
出典: GitHub: GHSA-6wmf-4rv5-p3rp、CVE.org レコード(API)、NVD: CVE-2026-109619(2026-10-22 08:16 JST 取得)
深刻度(出典ごと)
| 出典 | 版 | 点数 | ベクトル |
|---|---|---|---|
| PHP(security@php.net、CVE の採番元)/GitHub 勧告 | CVSS v4.0 | 9.2 Critical(2 件とも) | CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| NVD(nvd@nist.gov) | CVSS v3.1 | 9.8 Critical(2 件とも) | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
差の理由:PHP 側は「攻撃の複雑さ:高い(AC:H)」「攻撃に前提条件あり(AT:P)」としています(メモリ配置やワーカーの一致に左右されるため)。NVD は v3.1 で「複雑さ:低い(AC:L)」と付けています。どちらでも Critical で、ネットワーク越し・認証なし・利用者の操作なし、の 3 点は一致しています。
悪用の状況:CISA の「既知の悪用済み脆弱性(KEV)」には 2026-10-22 08:16 JST の時点で載っていません(KEV の JSON フィードを取得して確認、NVD レコードにも KEV の記載なし)。実際の攻撃が観測されたかどうかは、一次情報では未確認です。ただし事前予告には「詳細が漏れたり悪用が見つかったら前倒しする」とあり、当日出ているので、少なくとも予告時点で前倒しの理由は無かったと読めます(推論)。
出典: NVD API(CVE-2026-109618)、NVD API(CVE-2026-109619)、CISA KEV(2026-10-22 08:16 JST 取得)
影響する版と修正版
| 系統 | 影響する版 | 修正版 | 補足 |
|---|---|---|---|
| PHP 8.5 | 8.5.12 より前 | 8.5.12 | 脆弱性 2 の fatal_error_backtraces 経路は 8.5 だけ |
| PHP 8.4 | 8.4.27 より前 | 8.4.27 | |
| PHP 8.3 | 8.3.36 より前 | 8.3.36 | セキュリティ修正のみの期間 |
| PHP 8.2 | 8.2.35 より前 | 8.2.35 | 2026-12-31 でサポート終了と告知に明記 |
| PHP 8.6(開発中) | RC4 より前のテスト版 | 8.6.0 RC4 | 本番では使わないこと |
| PHP 8.1・8.0・7.4 | (勧告の範囲外だが、告知は「8.1 以前は PHP プロジェクトからの更新が無い」と明記) | 公式の修正版なし | 最小限のソースパッチのブランチだけ公開:7.4・8.0・8.1。ディストリや延長サポート業者のバックポートを確認するか、サポート中の版へ上げる |
CVE レコードと GitHub 勧告の「影響する版」は 8.2〜8.5 の 4 系統だけで、8.1 以前が影響を受けるかは明記されていません。ただし 7.4〜8.1 向けにパッチを用意している以上、古い版も影響を受ける前提で扱うべきです(推論)。
配布元について、告知は次も書いています。
- Linux ディストリと延長サポート業者には事前にパッチが渡っているので、各配布元の更新パッケージを確認する
- 有志運営の
rpms.remirepo.net(Remi リポジトリ)は当日は更新が出ない。ディストリのパッケージに切り替えるか、ソースからビルドすることを勧める
出典: php.net: Security advisory、php.net: ChangeLog 8、各 GHSA の Affected / Patched versions(2026-10-22 08:15〜08:17 JST 取得)
すぐ更新できないときの回避策(どれも完全ではない)
PHP の告知は「完全な回避策は無い。更新だけが安全な選択」「以下は特定の攻撃経路を狭めるだけで、安全にはしない」と書いています。
メモリ不足の脆弱性(CVE-2026-109618)に対して
memory_limit=-1(上限なし)にし、アプリが上書きできない方法(FPM プールや Apache 設定のphp_admin_value)で固定する。プール・ディレクトリ・アプリのどこかで有限の値に戻されていないか確認する。これでも OS 側のメモリ確保失敗からは到達しうるpost_max_sizeを低くする。アップロード不要なら 8M、必要なら 32M。upload_max_filesizeはそれより小さく- Web サーバー/プロキシ側で、展開後の本文サイズ・入力欄の数・multipart のパート数・ヘッダー数・入れ子の深さを制限する。
Content-Lengthの無いリクエストにも効くようにする - アプリが multipart を使わないなら、前段で multipart のリクエストを遮断する
- コンテナや cgroup のメモリ上限を「可用性の境界」として使う(そのワーカーだけ落ちる方針が望ましい)。
RLIMIT_AS・RLIMIT_DATAは逆効果(確保失敗を起こして脆弱な経路に入る)
前リクエストの状態が残る脆弱性(CVE-2026-109619)に対して
session.upload_progress.enabled=0にして全ワーカーを再起動。php.ini・FPM プール・サーバー設定など、リクエスト解析より前に効く場所で。ini_set()や FPM の.user.iniでは効かない。確認済みのセッション経路は塞げるが、他の変種は塞げない。勧告は不要なら更新後も切っておくことを勧めている- PHP 8.5 なら
fatal_error_backtraces=0にして全ワーカーを再起動 - リクエストごとに適用している設定のうち、無効・非推奨で警告を出すものを取り除く(警告を隠しても効かない)
- 攻撃者が起こせる致命的エラーと実行時間切れを潰す(コールバック、アップロードや取り込み処理、後片付けを含む)。予測できるタイムアウトを避ける
pm.max_requests=1(1 リクエストごとにワーカーを入れ替える)も検討に挙がっている。性能は大きく落ちる(一般論、未計測)E_ALLでログを監査する。ただしログだけでは安全の証明にならない
出典: php.net: Security advisory、GHSA-w8hw-w9fx-j79w、GHSA-6wmf-4rv5-p3rp
所見:Web アプリ開発者として、どれくらい気にすべきか
この節は一次情報からの私の判断です。出典の事実とは分けて読んでください。
- 「自分のアプリにその機能が無いから大丈夫」が通用しない種類です。脆弱性 1 は POST 本文の自動解析、脆弱性 2 は標準で有効なセッションのアップロード進捗という、PHP 本体が全リクエストに対して勝手にやる処理が入口です。WordPress・Laravel・自作のどれでも、PHP を Web で動かしていれば対象と考えるのが妥当です。WordPress 本体やプラグインの更新では直りません。
- 優先度が最も高いのは mod_php 構成(古めのレンタルサーバー、Apache+mod_php の自前 VPS、昔ながらの Docker イメージ
php:*-apacheなど)。勧告で唯一「アプリのコードより前に、認証なしで RCE」が実証された構成です。php:*-apacheイメージが mod_php であることは私の記憶で、一次情報では未確認です。 - PHP-FPM(nginx+FPM、多くのマネージド環境)も安全ではありません。脆弱性 2 のセッション経路は FPM でも RCE が検証済みです。ただし同じワーカーに 2 回当てる必要があるので、ワーカー数が多い大規模環境ほど成功率は下がります(それでも「下がる」だけ)。
- PHP 8.1 以前のまま残っている案件が一番危ない。公式の修正版が出ません。過去の受託案件や、更新が止まった WordPress サイトがあれば、ホスティング会社の対応状況を確認するか、8.2 以上へ上げる判断が要ります。8.2 も 2026-12-31 で終わるので、上げるなら 8.3 以上が無難です。
- レンタルサーバー・マネージド環境では、自分で PHP を更新できないことが多いので、事業者の告知を確認するのが実務です。確認は
phpinfo()や管理画面の PHP 版表示で、8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 以上か、あるいはディストリのパッケージなら配布元のセキュリティ告知で CVE-2026-109618/109619 の修正済み版か、を見ます(ディストリ版は版番号が上流と一致しないため)。 - 更新後の確認:メモリ不足時の止まり方が変わる修正なので、メモリ上限ぎりぎりの重いバッチや画像処理がある案件は、更新後に一度動かして挙動を見ておくと安心です。
- すぐ上げられない間は、効果と副作用のバランスから、
session.upload_progress.enabled=0(ほぼ誰も使っていない機能)と、post_max_sizeを現実的な値まで下げる、の 2 つが手を付けやすいと考えます。memory_limit=-1は別の資源枯渇の危険を増やすので、コンテナのメモリ上限とセットでのみ。 - 攻撃コードの公開状況・実際の悪用は 2026-10-22 08:16 JST の時点で一次情報からは確認できていません(KEV 未掲載)。ただ、詳細な技術情報が勧告に出ているので、「様子見」ではなく今週中の更新を勧めます。
参考:直前の 2026-09-24 のセキュリティリリース
依頼の対象ではありませんが、日付を取り違えていないかの確認として。1 つ前のセキュリティリリース(8.5.11・8.4.26・8.3.35・8.2.34、2026-09-24)は、FPM の IPv6 アクセス制御のすり抜け(CVE-2026-91768)、OpenSSL の証明書ホスト名検証の不備(CVE-2026-91769、CVE-2026-91767)、Phar の整数オーバーフロー(CVE-2026-6103)、SOAP、mysqlnd などを直したもので、今回とは別物です(ChangeLog 8 で確認。内容の詳細は未調査)。
出典(取得日 2026-10-22 08:15〜08:20 JST)
- php.net: Security advisory: Critical remote code execution vulnerabilities, update now(2026-10-21)
- php.net: Upcoming Critical PHP Security Release(2026-10-20)
- php.net トップのニュース(8.5.12・8.4.27・8.3.36・8.2.35・8.6.0 RC4 の告知)
- php.net: PHP 8 ChangeLog(取得して 8.5.12・8.4.27・8.3.36・8.2.35 の節から GHSA/CVE 番号を抽出)
- GitHub php/php-src: GHSA-w8hw-w9fx-j79w(RCE via OOM corruption)。報告者: lcfr-hax、sagitzadik-wiz、tomash-areion、amyb-oai。修正: arnaud-lb、iluuu1994、bukka、ndossche
- GitHub php/php-src: GHSA-6wmf-4rv5-p3rp(RCE via stale global state)。報告者・修正者は同じ顔ぶれ
- CVE.org: CVE-2026-109618(公開 2026-10-21 13:48 UTC)、CVE-2026-109619(公開 2026-10-21 13:54 UTC)
- NVD: CVE-2026-109618、CVE-2026-109619(API で取得。登録 2026-10-21 14:17 UTC、状態 Modified)
- CISA Known Exploited Vulnerabilities(JSON フィードで 2 件とも未掲載を確認)
- 記憶で補った部分:Docker 公式イメージの
php:*-apacheが mod_php であること、pm.max_requests=1の性能影響。いずれも本書では「未確認」「一般論」と明示