PHP2Shellオンライン脆弱性チェッカー

所有している、またはテストの許可を得たURLを入力してください。PHPの特徴、バージョンの手掛かり、フォーム応答を順に確認し、PHP2Shellのリスク評価と対策に役立てます。

2

PHPコアの脆弱性

9.2

CVSS v4.0スコア(緊急)

4

上流で修正された8.2~8.5のブランチ

脆弱性の概要

PHP2Shellとは?なぜ早急な確認が必要なのか

PHP2Shellは、PHPコアのメモリ安全性に関するCVE-2026-109618とCVE-2026-109619の総称です。どちらもCVSS v4.0で9.2と評価されています。認証なしでリモートコードを実行される可能性があり、影響はバージョン、実行環境、攻撃経路によって異なります。

PHPの公式告知を読む

影響を受けるのはアプリだけでなくPHPエンジン

PHP-FPM、Apache mod_php、php-cgi、FrankenPHP、LiteSpeedなど、Webリクエストを処理するPHP環境をすべて確認対象に含めてください。PHP公式はmod_phpを最も高リスクとし、アプリコードの実行前に成立する攻撃を実証しています。単純なページや安全なアプリコードでもリスクは排除できません。

サイトの更新に加えて実行環境も確認

WordPress、Drupal、フレームワーク、プラグインの更新だけでは、使用するPHPも更新されたとは限りません。各サイトのPHPバージョン、FPMプール、コンテナイメージ、複数のノード、管理パネルや機器に組み込まれたPHPを個別に確認してください。公式修正版は2026年10月21日に公開されました。

検査する内容

PHPの特徴、リクエスト応答、パッチ状況を確認

7種類のリクエストは何の確認に役立つ?

まず基準となるGETを取得し、3種類のメソッドごとに通常のフォームとmultipartフォームを送信します。応答を1件ずつ確認してから次へ進みます。動作を比較する通常のリクエストであり、コード実行やメモリ枯渇を狙うペイロードは含みません。

PHP2Shellの調査に使う7種類のHTTPリクエスト
順序 メソッド 送信内容 確認する点
01GETリクエスト本文なしページの到達性、リダイレクト、公開PHPバージョン、応答ヘッダー。
02POSTapplication/x-www-form-urlencodedPOSTの対照となる通常のテキストフィールド1個。
03POSTmultipart/form-dataPOST対照と比較するテキストフィールド1個。ファイル部分やアップロード進捗フィールドは追加しません。
04PUTapplication/x-www-form-urlencodedこのパスのPUT処理を確認する通常のテキストフィールド1個。
05PUTmultipart/form-data通常のPUTフォームと比較し、コンテンツタイプによる応答差を確認します。
06PATCHapplication/x-www-form-urlencodedPATCHの対照となる通常のテキストフィールド1個。
07PATCHmultipart/form-dataPATCH対照と比較し、POSTだけから他メソッドの動作を推測しないようにします。

X-Powered-ByやServerのPHP表記、PHPSESSIDのようなセッションCookieは実行環境の手掛かりにすぎません。非表示、書き換え、カスタマイズが可能です。CookieがあってもPHPによるリクエスト本文の解析は証明できません。

この検査は入力されたURLとパスのみを対象とします。別のルート、CDNルール、直接接続できるオリジンサーバーでは動作が異なる場合があります。トップページの結果をサイト全体に当てはめないでください。許可を得た、フォームリクエストに適したパスだけを検査してください。

検査結果の読み方

露出の手掛かりと確認済みの修正を区別

公開レスポンスから得られる証拠は一部だけです。バージョンが非表示・変更されていたり、旧版にベンダーのバックポートが適用されていたりします。証拠不足を安全と誤認せず、実際の実行環境を確認してください。

よくある判断ミスを確認

修正済みバージョンの手掛かりあり

公開バージョンが該当ブランチの修正版以上なら有用な手掛かりですが、プロキシがヘッダーを書き換える場合があります。全インスタンスが修正コードを読み込んでいるか、サーバーで確認してください。

旧バージョンによるリスクの手掛かりあり

上流の修正版未満は優先確認の対象ですが、ディストリビューションやLTSベンダーがバックポート済みの可能性があります。適用状況が不明なら要確認とし、リモートコード実行を検証済みと断定しないでください。

リクエストの拒否や応答の違いあり

通常フォームが成功しmultipartが4xxなら、コンテンツタイプの制限かもしれません。両方405なら、そのパスがメソッドをサポートしていないだけの可能性もあります。ステータスコードだけではCDN、Webサーバー、アプリのどこで拒否されたか判別できません。

PHPの手掛かりなし、または応答を取得できず

バージョンの非表示、プロキシキャッシュ、独自Cookie、接続失敗、タイムアウトは判断を制限します。証拠不足や評価不能として記録し、不足する証拠を緑色の安全判定で置き換えないでください。

検査の流れ

URLを入力し、リスクの手掛かりを順に確認

1

対象URLを入力

所有またはテスト許可のあるサイトのURLを、確認対象のパスまで入力します。

2

1件ずつ検査して応答を確認

GET基準応答を確認し、POST・PUT・PATCHそれぞれの通常フォームとmultipartの応答を順番に比較します。

3

リスクの手掛かりと対策を確認

ステータスコードとバージョンの手掛かりを解釈し、実際のPHP環境とベンダー告知からパッチ状況を確認します。

サーバー側での確認

サイトが修正済みPHPで動いているか確認するには?

外部検査は手掛かりの発見に役立ちますが、パッチ状況はホスト、コンテナ、ホスティング管理画面で確認する必要があります。以下の順で実行環境、パッケージの提供元、修正版、更新後のプロセス状態を記録してください。

1. 実際にリクエストを処理するPHPを特定

サイトに割り当てられたPHP、Webサーバーモジュール、FPMプールを確認します。複数バージョン、複数サイト、コンテナ、負荷分散ノードは個別に棚卸ししてください。php -vは現在のCLI版を示すだけで、Web版とは限りません。確認のためにphpinfoページを公開しないでください。

php -v

2. 完全なパッケージバージョンと告知を照合

実際のパッケージを照会し、完全なバージョンをディストリビューションのセキュリティ告知と照合します。Ubuntu 24.04の8.3.6-0ubuntu0.24.04.13には修正が含まれますが、PHP 8.3.6だけではバックポートを判断できません。以下から適切な照会例を選び、実際のパッケージ名に置き換えてください。

dpkg-query -W php8.3-fpm
rpm -q php-fpm
Ubuntu公式の修正パッケージ一覧

3. 該当ブランチの修正版を適用

該当ブランチの上流修正版、後続のセキュリティ版、またはベンダー確認済みのバックポートを使用します。管理パネル、機器、コンテナに含まれるPHPは各提供元の手順で更新してください。PHP 8.1以前は通常の上流サポートが終了しているため、LTS修正を確認するか移行が必要です。今回は7.4、8.0、8.1向けの最小限のソースバックポートも提供されています。

4. 再起動し、全インスタンスを再確認

PHP-FPM、Apacheなどのワーカーを再起動し、コンテナや複数ノードの置き換えが完了したか確認します。ディスク上のパッケージが更新されても旧プロセスが稼働している場合があります。異常なリクエスト、メモリ不足、ワーカーのクラッシュ記録は調査に役立ちますが、記録がないことは影響なしの証明にはなりません。

自分で確認:curlで7項目をチェック

スクリプトはGETを1回、その後POST・PUT・PATCHでURLエンコードとmultipartのフォームを順番に送信します。通常のテキストフィールドのみを使い、ファイルやアップロード進捗フィールドは送りません。許可済みでテストフォームに適したパスだけで実行してください。通常のリクエストでも業務処理が動く場合があります。

Bash / curl
#!/usr/bin/env bash
# PHP2Shell HTTP observations: 7 sequential requests, no exploit payload.
set -u

URL="${1:-https://example.com/}"
case "$URL" in
  http://*|https://*) ;;
  *) printf 'ERROR=HTTP(S)_URL_REQUIRED\n' >&2; exit 2 ;;
esac

if ! command -v curl >/dev/null 2>&1 || ! command -v awk >/dev/null 2>&1; then
  printf 'ERROR=CURL_AND_AWK_REQUIRED\n' >&2
  exit 127
fi

probe() {
  printf '\n[%s/7] %s %s\n' "$1" "$2" "$3"
  local method="$2"
  shift 3
  curl -q --globoff --proto '=http,https' --silent --show-error \
    --connect-timeout 5 --max-time 15 --request "$method" \
    --dump-header - --output /dev/null \
    --write-out '\nHTTP_CODE=%{http_code} TOTAL_SECONDS=%{time_total}\n' \
    "$@" --url "$URL" |
  awk '{
    sub(/\r$/, "")
    line = tolower($0)
    if ($0 ~ /^HTTP\// || line ~ /^(server|x-powered-by|content-type):/ || $0 ~ /^HTTP_CODE=/) {
      print
    } else if (line ~ /^set-cookie:[ \t]*phpsessid[ \t]*=/) {
      print "PHPSESSID=present; value hidden"
    }
  }'
  local curl_status="${PIPESTATUS[0]}"
  if [ "$curl_status" -ne 0 ]; then
    printf 'CURL_EXIT=%s\n' "$curl_status"
    FAILED=1
  fi
}

FAILED=0
probe 1 GET baseline
probe 2 POST urlencoded --data-raw 'php2shell_check=1'
probe 3 POST multipart --form-string 'php2shell_check=1'
probe 4 PUT urlencoded --data-raw 'php2shell_check=1'
probe 5 PUT multipart --form-string 'php2shell_check=1'
probe 6 PATCH urlencoded --data-raw 'php2shell_check=1'
probe 7 PATCH multipart --form-string 'php2shell_check=1'
exit "$FAILED"

Linux/macOSのBash、またはWindowsのWSL・Git Bashを使用します。php2shell-self-check.shとして保存し、下記コマンドのURLを許可済みのテストページに置き換えて実行してください。Bashスクリプト全体をPowerShellに直接貼り付けないでください。

bash php2shell-self-check.sh https://example.com/test.php

接続のタイムアウトは5秒、各リクエスト全体は15秒です。個人のcurl設定を無視し、TLSを検証してリダイレクトや再試行は行いません。3xxの場合は最終URLも許可範囲内か確認し、そのURLで再実行してください。PHPSESSIDは存在だけを表示し、Cookie値や応答本文は出力しません。

HTTP_CODEは応答ステータス、TOTAL_SECONDSは総所要時間です。CURL_EXITが0以外ならその転送が失敗しましたが、残りの検査は続きます。スクリプトの終了コードが0以外なら入力・依存コマンド・転送の問題を示します。HTTP 4xx/5xxは通常どおり記録され、終了コードで脆弱性やパッチ状況は判定できません。

ターミナル出力の読み方

バージョンヘッダーは手掛かり

ServerやX-Powered-Byは非表示、または古い情報の場合があります。サイトで実際に稼働するPHPを確認してください。各ブランチの最初の公式修正版は8.2.35、8.3.36、8.4.27、8.5.12です。ベンダーのバックポートは完全なパッケージバージョンとセキュリティ告知で確認します。

同じメソッドの2種類のエンコードを比較

同じメソッドでurlencodedが2xxまたは3xx、multipartが403または406を返しても、分かるのは応答の違いだけです。WAFによる遮断や、PHPに到達する前の拒否を確認したことにはなりません。

成功応答はPHPによる解析の証明ではない

multipartの2xxや3xxは、成功応答またはリダイレクト応答を受信したことだけを示します。本文がPHPに渡されて解析された証明にはならず、脆弱性の有無も判断できません。

405やPHPの表示だけでは結論を出せない

すべて405でも修正済みとは限りません。PHPの表示がなくても未使用とは限らず、PHPSESSIDがあってもmultipartの解析や、どのレイヤーが応答したかを確定できません。

公式修正版と更新の案内を確認
すぐに更新できない場合、緩和策でできることは?

PHP公式は、完全な修正には更新が必要と明言しています。以下の設定は一部の既知経路を減らすだけで、未修正環境を安全にはしません。変更前にアプリ要件と公式告知を確認してください。

  • session.upload_progress.enabledを無効にし、全ワーカーを再起動します。リクエスト解析前にphp.ini、FPMプール、サーバー設定で有効にし、ini_set()やFPMの.user.iniには依存しないでください。遮断するのは確認済みのsession経路のみです。
  • PHP 8.5では、公式の案内に従いfatal_error_backtracesを無効にしてワーカーを再起動します。対象は確認済みのfatal backtrace経路のみで、ほかの亜種には対応しません。
  • Webサーバーやプロキシで本文サイズ、フィールド数、multipartパート数などの制限を確認し、CDNを経由せずオリジンに接続できないか調べます。エラーを隠す、1種類のメソッドだけを拒否する、1パスだけを検査することは修正の代わりになりません。

公式修正版

PHP 8.2~8.5の各ブランチの修正開始版を確認

バージョンはブランチごとに比較します。8.3の修正基準で8.4を判定することはできません。プレビュー版や未知のブランチを修正済みと決めつけないでください。バックポートや独自ビルドは完全なパッケージバージョン、ビルド記録、ベンダー告知で確認します。

公式の更新推奨事項を読む

宝塔パネルをお使いですか?ソフトウェアストアからPHPを更新

宝塔の2026-10-21付の告知によると、一部のPHPセキュリティ修正版がパネルに反映されています。実際に更新できるバージョンは、お使いの宝塔パネルのソフトウェアストアで確認してください。

宝塔の更新告知を読む

更新前にサイト、データベース、関連設定をバックアップし、適切なメンテナンス時間を選んでください。

  1. サイトが実際に使用するPHPを確認

    宝塔パネルにログインし、「ソフトウェアストア → インストール済み」から現在のサイトが使用するPHPバージョンを探し、管理画面を開きます。

  2. 対応するブランチのセキュリティ版に更新

    そのPHP管理画面で利用可能な更新を確認し、案内に従って上記の同じブランチの修正版、または同ブランチの後続セキュリティ版に更新します。

  3. サービスを再起動してサイトを確認

    更新後に対応するPHPサービスを再起動し、すべてのワーカーが再読み込みされたことを確認します。サイトが実際に使用するPHPバージョンを確認し、ページ表示、アップロード、データベース接続などをテストしてください。

複数のPHPバージョンをインストールしている場合は、使用中のものをそれぞれ確認してください。別のバージョンを新規インストールした場合は、サイトが修正済みのPHP実行環境に切り替わっていることも確認します。

よくある質問

PHP2Shellの検査と修正に関するよくある質問

バージョンの手掛かり、ステータスコード、バックポートの違いを理解し、結果の過大解釈を防ぎます。

PHP2Shellとは何ですか?どのサイトに確認が必要ですか?

PHP2ShellはPHPコアの脆弱性CVE-2026-109618とCVE-2026-109619を指し、認証なしのリモートコード実行につながる可能性があります。Webリクエストを処理する未修正のPHP環境はすべて確認が必要で、アプリコードが安全でもリスクは排除できません。

403・405・413なら保護されていると言えますか?

いいえ。認証、非対応メソッド、サイズ制限、プロキシでもこれらのコードが返ります。multipartが拒否されても現在のパスの動作を示すだけで、PHPの修正や全攻撃経路の遮断は証明できません。

PHP応答ヘッダーがなければ影響なしですか?

それだけでは判断できません。バージョン公開が無効だったり、CDN、リバースプロキシ、静的トップページがバックエンドを隠していたりします。特徴がない場合は情報不足とし、実際のサーバー環境を確認してください。

どのバージョンに更新すべきですか?旧版は必ず未修正ですか?

上流修正版はPHP 8.2.35、8.3.36、8.4.27、8.5.12です。該当ブランチの修正版または後続のセキュリティ版を使用してください。旧版にもバックポートが含まれる場合があるため、完全なパッケージバージョンとベンダー告知を照合します。PHP 8.1以前は通常の上流保守が終了しています。更新後は関連ワーカーを再起動してください。

POST以外にPUTとPATCHも調べる理由は?

メソッドによってルートやフィルタールールが異なる場合があります。PHP 8.4以降はrequest_parse_body()でPOST以外のmultipartも解析できますが、すべてのアプリがPUTやPATCHを自動解析するわけではありません。POSTの動作だけで他メソッドやパスの保護は判断できません。

POSTが200、PUT/PATCHが405でPHP表記もない場合は?

PHP実行環境とパッチ状況は未確認として記録します。POSTの200は応答したことだけ、405はいずれかの層がメソッドを拒否したことだけを示します。静的ページ、別のバックエンド、特徴を隠したPHPでもこの組み合わせになります。安全・脆弱性検証済みと断定せず、サーバーの実行環境を確認してください。

脆弱性と修正に関する資料の確認日は2026-10-22です。外部からの観察には限界があるため、実際の対応は最新のPHPおよび各ベンダーの告知に従ってください。

サイトのPHP2Shellリスクをより明確に

公開応答を1件ずつ確認し、証拠からリスクを理解して、実際のサーバー環境でパッチと修正を確かめます。

検査項目を詳しく見る