2026/11/21にPHPの重大脆弱性が発表されました。
認証なしのリモートコード実行につながる2件を修正したとのとで、
オランダの国家サイバーセキュリティセンター(NCSC-NL)はこの2件を
「php2shell」と呼んでいます。
対象は、Webリクエストを処理するすべてのPHP
(PHP-FPM・Apache mod_php〔Apache に組み込んで動かす方式〕・php-cgi・FrankenPHP・LiteSpeed)。
影響バージョンは 8.2.35/8.3.36/8.4.27/8.5.12 より前のバージョンすのべてです。
今回発見された脆弱性
CVE-2026-109618
RCE via OOM corruption(メモリ不足の処理での破損によるリモートコード実行)
PHPは、メモリ不足(OOM)のエラーが起きると処理を途中で打ち切ります。PHP公式によると、リクエストの内部データが一部しか初期化されていないタイミングで打ち切られると、後片付けの処理がその不完全なデータを正しいものとして扱ってしまうことがあります。GHSAでは、multipart形式(ファイルのアップロードなどで使う形式)の解析で、PHPの制限内のままメモリ不足に至る方法が複数あるとしています。
mod_php では、開始処理が失敗しても後片付けの処理が必ず実行されるため、アプリのコードが動く前に問題が起きます。WordPressのセキュリティプラグインのような、アプリ側の対策より前の段階です。FPMについては、ソースの分析上は影響を受けるとされています(完全な攻撃の実証はない、とも明記)。
影響:認証なしでのリモートコード実行(Webワーカーのアカウントの権限で)
CVE-2026-109619
RCE via stale global state(古いグローバル状態の再利用によるリモートコード実行)
PHPのワーカーは複数のリクエストを順番に処理します。PHP公式によると、あるリクエストの内部の状態がメモリの解放後も残り、同じワーカーが処理する次のリクエストが、初期化の前にその古い状態を使ってしまうことがあります。GHSAは、致命的なエラー(メモリ不足を含む)で本来のリセットが行われないことを原因の一つに挙げ、PHP 8.5 の致命的エラーのバックトレース機能と、セッションのアップロード進捗機能(初期設定で有効)を使う経路を「確認済み」としています。
緩和策の表に fatal_error_backtraces と session.upload_progress.enabled が出てくるのはこのためです。なお、セッションの経路によるリモートコード実行は、mod_php だけでなく PHP-FPM でも検証済みとされています(GHSA)。
影響:認証なしでのメモリの解放後使用(use-after-free)、メモリ内容の漏えい、リモートコード実行
影響範囲を調査する
#バージョンの確認
php -v
#PHPのコンフィグファイルの場所の確認
php –ini
これ以下の場合は、対策が必要です。
・PHP 8.5系、PHP 8.5.11 以下
・PHP 8.4系、PHP 8.4.26 以下
・PHP 8.3系、PHP 8.3.35 以下
・PHP 8.2系、PHP 8.2.34 以下
PHPのコンフィグを確認
php -i
また、WebサーバからプラグインからPHPを起動しているような場合もあるので、
注意が必要です。
Apache mod_php、php-cgi、FrankenPHP、LiteSpeed、PHP-FPM
| 実行形態 | 公式の見立て |
|---|---|
| Apache mod_php | 最も危険。認証なし・アプリのコード実行前の攻撃が実証済み |
| FrankenPHP、LiteSpeed(LSAPI) | 影響を受ける可能性が高い |
| PHP-FPM | 影響を受ける可能性がある(完全なエクスプロイトは未実証) |
なお、今回の脆弱性は、アップロード機能の不具合を元にしたものですが、
ファイルのアップロード画面がないサイトでも影響を受けます。
PHPは、アプリのコードが動く前にmultipart/form-data形式のリクエストを解析します。
攻撃に使われる処理はこの段階で起きるため、PHPで処理されるURLであれば、
どこでも攻撃の入口になりえます。
一番版確実なのは、
該当サイトでphpinfo()を出すファイルを一時的に置いてブラウザで開き、
バージョンとServer API(mod_php/FPMなど)を確認します。
以下の内容のファイルを作成して一時的に配置してください。
php_info_klaiskw.php
<?php phpinfo(); ?>: PHPのバージョンやモジュール、サーバー環境などの機密情報が外部に漏洩するリスクがあるため、確認が終わったら必ずサーバーからファイルを削除してください。。
PHP公式よりパッチが公開されました(PHP 8.2 – 8.5)
10/21にサポート対象期間であるPHPについては、
対策パッチを当てたバージョン PHP 8.5.12・8.4.27・8.3.36・8.2.35 が公開されました。
・PHP 8.5系、対策済バージョンはPHP 8.5.12
・PHP 8.4系、対策済バージョンはPHP 8.4.27
・PHP 8.3系、対策済バージョンはPHP 8.3.36
・PHP 8.2系、対策済バージョンはPHP 8.2.35
このバージョンを現在使っているのであれば、
OS・ベンダーが配布する修正済みパッケージに更新し、
PHPのワーカー(リクエストを処理するPHPのプロセス)を再起動すればOKです。
同じ系統(PHP 8.5.x->8.5.12等)であれば、基本的な仕様変更も少ないので、
比較的影響を抑えることができます。
更新方法
debian系更新例
sudo apt update
sudo apt –only-upgrade install php8.3*
更新後は php8.3-fpm や httpd などのサービス再起動が必要
Redhat系更新例
sudo dnf upgrade php
更新後は php-fpm や httpd などのサービス再起動が必要
Dockerで導入されたイメージ内のPHPのバージョンアップ
Dockerで構築したアプリ内のPHPバージョンをバージョンアップする場合は、
docker-compose.yml(またはcompose.yaml)のイメージタグを書き換えてコンテナを再作成します。
更新の手順
- バックアップを取る
- データベース(MySQL / MariaDB)のダンプと、WordPressのアップロードファイル(
wp-contentなど)を事前に保存します。
- データベース(MySQL / MariaDB)のダンプと、WordPressのアップロードファイル(
docker-compose.ymlを編集する- WordPress公式イメージのタグ(例:
wordpress:php8.1-apacheやwordpress:6-php8.2など)を、使いたい新しいPHPバージョンやWordPressバージョンに変更します。
services:wordpress:
image: wordpress:php8.5-fpm-alpine # 例: PHPのバージョンを変更 ...
コードは注意してご使用ください。- WordPress公式イメージのタグ(例:
- コンテナを停止してイメージをプルする
- 以下のコマンドを実行して最新のイメージをダウンロードし、コンテナを再構築します。
docker compose downdocker compose pulldocker compose up -d
コードは注意してご使用ください。 - 動作確認をする
- ブラウザでサイトにアクセスし、管理画面からWordPressやPHPのバージョンが正しく更新されているか確認します。
ただし、古いイメージから急に細心にアップデートとすると証方式の違いや古い暗号化プロトコルの影響で接続エラーになる可能性が非常に高いです。
このため、複数のステップに分けて移行する必要があります。
カリとして、5年前に最後に更新したwordpress & mysql 5.7を最新死しようとした際に
以下のような手順を踏む必要があります
(WordPress自体のアップデートは随時実施する前提で、最新版に更新済)。
| 段階 | WordPress/PHP タグ | MySQL タグ | phpMyAdmin タグ | 作業内容 |
|---|---|---|---|---|
| 現在 | wordpress:latest (中身は古いPHP) | mysql:5.7 | phpmyadmin:latest | 現状の環境 |
| Step 1 | wordpress:6.7-php8.3-apache | mysql:5.7 | phpmyadmin:latest | まずPHP環境だけを最新(8.3)に切り替える |
| Step 2 | wordpress:6.7-php8.3-apache | mysql:8.0 | phpmyadmin:latest (再取得) | MySQLとphpMyAdminを最新にする |
| Step 2 | wordpress:7.1-php8.3-apache | mysql:8.0 | phpmyadmin:latest | WordPressを細心にする(PHP8.3.26) |
Step1 wordpressを更新(いきなり最新ではなく、6.7-php8.3-apacheに更新)
docker-compose.yml の wordpress: のタグを書き換え
wordpress:latest -> wordpress:6.7-php8.3-apache
docker compose down
docker compose up -d
作業完了後、ブラウザにアクセスしたところ、
「このサイトで重大なエラーが発生しました。」と表示されました。
phpを7.4から8.3にあげたことでプラグインやテーマの起動に失敗した
可能性があるので、以下のコマンドで、ログを確認します
docker compose logs wordpress | grep -i fatal
すると、PHPがどこでクラッシュしたかのログが表示表示されますが、
いくつかのプラグインでエラーになっていたので、wp-content/plugins/
にあるプラグインフォルダをリネームすると強制的に無効化します。
wp-content/plugins/old-plugin -> old-plugin_bak
再度ブラウザでアクセスすると、起動することができました。
(まだ起動できないときはあたらめてログを確認します)
Step2 mysqlとphpmyadminを更新
docker-compose.yml の mysql: のタグを書き換え
mysql:5.7 -> mysql:8.0
docker compose pull phpmyadmin
docker compose down
docker compose up -d
起動後、PHPのバージョンを確認したところ、
8.3.20で、最新のパッチ(8.3.36)が当たっていませんでした。
docker compose exec wordpress php -v
8.3.20
Step3 wordpressを最新に更新
docker-compose.yml の wordpress: のタグを書き換え
wordpress:wordpress:6.7-php8.3-apache -> wordpress:7.1-php8.3-apache
docker compose down
docker compose up -d
起動後、PHPのバージョンを確認したところ、
最新のパッチが当たっていることを確認しました。
docker compose exec wordpress php -v
8.3.36
サポート対象外の古いPHPのパッチは?
問題はDocker以外で導入したPHPが
対策済パッケージのない、サポート対象外の古いバージョンだった場合です
設定による緩和策はあるようですが、これは既存の攻撃経路を潰すのが目的の対処策で、
設定による完全な対策はできないとのことで、あくまで更新までのつなぎの位置づけです。
最終的には、サポートされているバージョンに挙げる必要が出てくるのですが、
PHPはバージョンによって仕様が変更される傾向があるため、
バージョンアップによって、PHPで作成されたコンテンツが正常に動作するかは
細かく確認する必要があります。
今回はかなり危険度が高いということで、一部の過去バージョン(EOL済)については
一応ソースレベルのパッチを当てたものも用意してくれているようです。
unofficial なものも見つけましたが、こちらについては自己責任でのご利用をお願いします。
こちらでは、7.4,8.0,8.1だけでなく、7.0-7.3もphp-src 7.4の修正を基に作られているそうです。
php-eol-CVE-2026-109618-109619/patches at main · mpyw/php-eol-CVE-2026-109618-109619 · GitHub
すぐに更新できない場合の緩和策
すぐに更新できない場合の緩和策として
php.iniに以下の行を追加で暫定対策になるみたいだけど、実際どうなるか・・・・
php.iniの場所は,php –iniで確認できます。
対策案は以下のようなものがありますが、
すべてで緩和策になっているのであくまで暫定対応で時間稼ぎにしかなりません。
確実なのは、パッチを適用したPHPを使うことです。
| 暫定策 | 効く脆弱性 | 副作用・注意点 | 完全か |
|---|---|---|---|
| WAF(Cloudflareなど)のルールを有効にする | 両方(既知の攻撃パターン) | WAFを通る通信しか守れない。攻撃側はルールを避けるためペイロードを変えている | 不完全 |
memory_limit=-1をFPMプールやApacheのphp_admin_valueで強制する | CVE-2026-109618 | メモリを使い切るリスクがある。コンテナやcgroupで上限をかけ、使用量を監視する | 不完全 |
post_max_sizeを下げる(不要なら8M、必要なら32M)、upload_max_filesizeをそれより小さくする | CVE-2026-109618 | 大きなファイルのアップロードができなくなる | 不完全 |
| Webサーバーやプロキシで、本文サイズ・フィールド数・multipartのパート数・ヘッダー数・入れ子の深さを制限する | CVE-2026-109618 | 正常なフォーム送信が弾かれないか確認が必要 | 不完全 |
session.upload_progress.enabled=0をphp.iniやFPMプールで設定し、全ワーカーを再起動する | CVE-2026-109619 | アップロードの進捗表示が使えなくなる。ini_set()や.user.iniでは効かない | 不完全 |
PHP 8.5でfatal_error_backtraces=0にし、全ワーカーを再起動する | CVE-2026-109619 | エラー時のバックトレースが出なくなる | 不完全 |
pm.max_requests=1(ワーカーを毎回作り直す) | CVE-2026-109619 | 性能が大きく落ちる | 不完全 |
| multipart/form-dataをWebサーバーで遮断する | 両方(既知の引き金) | アップロード、問い合わせフォーム、決済が使えなくなることがある | 不完全 |
| GETとHEADだけを許可する | 両方(既知の引き金) | 閲覧はできるが、ログイン・注文・投稿はできない | 不完全 |
| PHPを止めて、静的なメンテナンスページを出す | 両方 | サービスが止まる | 停止中は攻撃を受けない |
参考
PHPの重大脆弱性php2shellは自分のサイトも対象?修正版と確認手順 – satimo-blog
Views: 1