最初に一番大事なことを書きます。PHPの重大な脆弱性(通称PHP2Shell)への対策は、修正版への更新だけです。PHPの公式発表も、この記事で紹介する設定は特定の攻撃の経路を減らすだけで、それでサーバーが安全になるわけではない、としています。

それでも、古いアプリがすぐには新しいPHPで動かない、更新の作業が週末になる、といった事情はあります。そういうときに、更新までの数日を少しでも安全にするための、php.iniの脆弱性対策です。

php.iniは、PHPの動き方を決める設定ファイルです。自分でサーバーを管理している方向けの内容で、レンタルサーバーを使っている方は、会社が修正版を適用しているかを確かめるほうが先です。

1. メモリの上限を外す(1件目の欠陥向け)

1件目の欠陥(CVE-2026-109618)は、メモリが足りなくなったときの処理で起きます。PHPの公式発表は、PHPのメモリの上限をなくすことで、攻撃者が狙って起こせるメモリ不足をなくす設定を挙げています。

PHP-FPM(PHPをWebサーバーとは別のプログラムとして動かす方式)なら、プール(PHP-FPMがサイトごとなどに分けて持つ、ワーカーのまとまり)の設定ファイルにこう書きます。

php_admin_value[memory_limit] = -1

普通の memory_limit ではなく php_admin_value で書くのは、サイトのプログラムの側から上書きできないようにするためです。ほかの設定ファイルやディレクトリごとの設定で、上限が戻っていないかも確かめてください。

Apacheに組み込む方式(mod_php)なら、Apacheの設定に php_admin_value memory_limit -1 と書きます。

ただし、副作用があります。上限を外すと、1つのリクエストがサーバーのメモリを使い切る危険が増えます。発見者のCalifも、この点を注意しています。また、OSの側でメモリの確保に失敗した場合は、やはり欠陥の経路に入りうると、公式発表に書かれています。

2. 送れるデータの量を絞る

あわせて、1回のリクエストで送れるデータの量を絞ります。PHPの公式発表が挙げている目安はこうです。

; ファイルのアップロードが不要なサイト
post_max_size = 8M
; アップロードが必要なサイト
; post_max_size = 32M
; upload_max_filesize は post_max_size より小さく

さらに、Webサーバーやその前段のプロキシ(サーバーの手前で通信を中継する仕組み)で、リクエストの大きさ、入力欄の数、ヘッダー(通信に付く宛名のような付帯情報)の数などに上限をかけることも勧められています。

ここで注意が1つ。OSのメモリ制限(RLIMIT_AS や RLIMIT_DATA)で代わりにしようとしてはいけない、と公式発表は書いています。それ自体が、欠陥の経路に入るメモリ不足を起こしうるからです。代わりに勧められているのは、コンテナ(アプリを他から区切って動かす箱のような仕組み)やcgroup(Linuxでプログラムの使える資源を区切る仕組み)でメモリの上限をかけ、超えたときは該当のワーカー(リクエストを処理するプログラム)だけを止める方法です。

3. アップロードの進み具合の記録を止める(2件目の欠陥向け)

2件目の欠陥(CVE-2026-109619)の入口として確認されたのが、ファイルのアップロードの進み具合を記録するセッション(同じ訪問者の操作をページをまたいで覚えておく仕組み)の機能です。最初から有効になっているので、止めます。

session.upload_progress.enabled = 0

設定する場所が重要です。php.ini、PHP-FPMのプール、Webサーバーの設定のように、リクエストの読み込みより前に効く場所に書きます。プログラムの中の ini_set() や、PHP-FPMの .user.ini では遅すぎて効きません。

4. PHP 8.5ならエラーの詳細の記録を止める

PHP 8.5を使っている場合は、致命的なエラーのときに詳しい記録を残す機能も、確認された入口の1つです。

fatal_error_backtraces = 0

これもPHP 8.5の既定では有効です。止めても、確認された経路の1つがふさがるだけです。

公式発表は、あわせて2つの見直しも挙げています。リクエストごとに効く設定のうち、無効なものや非推奨のものを取り除くこと。そして、外から起こせる致命的なエラーや実行時間切れを、プログラムの側で直しておくことです。

5. すべてのワーカーを再起動する

設定を変えたら、PHPのワーカー(リクエストを処理するプログラム)をすべて再起動します。動き続けているワーカーには、新しい設定が届きません。

sudo systemctl restart php8.3-fpm

サービス名は環境によって違います。Apacheのmod_phpなら、Apacheを再起動します。

私は今回、設定を書き換えたあと再起動を忘れていて、確認のつもりで見た設定の画面が古い値のままでした。php.iniの脆弱性対策は、再起動までが1セットです。

効かない対策と、本当の対策

最後に、効かないとはっきり書かれている対策を挙げておきます。エラーの表示を隠すこと(error_reporting や display_errors の変更、@ の付与)は、2件目の欠陥には効かないと公式発表に書かれています。

もう1つ、米国のCISAは、すぐに更新できない場合はPHPで動くシステムをオフラインにすることを求めています。ここまでの設定で動かし続けるのは、止められない事情があるときの最後の手段だと考えてください。

ここまでのphp.iniの脆弱性対策は、あくまで更新までのつなぎです。WAF(Webサイトの前で怪しい通信を止める仕組み)も、CloudflareなどがPHP2Shell向けのルールを用意していますが、Cloudflare自身が修正の代わりにはならないとしています。設定を入れたら、更新の日程を決めてください。

更新を終えたら、更新前に侵入されていなかったかの確認もしておくと安心です。