fix-php-vuln について
fix-php-vulnは、PHP2Shellの影響を受けるPHPランタイムを特定し、承認済みリポジトリを修正するエージェント向けスキルです。読み取り専用の棚卸しと承認後、テストと成果物の確認でベンダービルドを検証し、個別のPRを準備します。
主な機能
- 01PHP導入箇所の読み取り専用調査
- 02ビルドを脆弱・修正済み・不明に分類
- 03修正を含むベンダー版の選定と確認
- 04ビルド済みランタイムのテストと比較
- 05個別PRと展開手順の準備
活用シーン
- 01リポジトリ内の公開対象SAPIとPHP版を特定
- 02承認済み環境を修正済みベンダービルドへ更新
- 03古いPHPブランチとアップグレード経路を評価
- 04展開前にテスト結果とランタイム変更を確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ cognitionai/ devin-vuln-fixes --skill fix-php-vulnインストール後、Claude Code で/fix-php-vulnを入力して読み込まれたか確認します。
詳細
PHP の脆弱性を修正する(PHP2Shell、CVE-2026-109618 / CVE-2026-109619)
概要
PHP2Shell の影響を受ける PHP ランタイムを検出して修正します。これは、2026-10-21 に 8.2.35、8.3.36、8.4.27、8.5.12 で修正された、認証不要の重大な RCE 2 件(CVSS v4 9.2)です。PHP 8.1 以前も影響を受けますが、リリースは提供されず、ソースへのバックポートのみとなります。PHP によると、ウェブを提供するすべての SAPI がリスクにさらされています(mod_php が最も高く、FPM、php-cgi、FrankenPHP、LiteSpeed も含まれます)。組み込みの php -S サーバーもリスクにさらされているものとして扱い、本番環境向けではないことを明記してください。まず読み取り専用でインベントリを作成します。編集の前に承認を待ちます。承認された各リポジトリを、修正済みのベンダービルドに更新し、ビルド成果物を検証して、対象を絞った PR を作成します。完全な修正方法はアップグレードのみです。
ユーザーに必要な情報
- スキャンするリポジトリまたは組織。既定では、ユーザーが指定したリポジトリ、またはエージェントがアクセスできるすべてのリポジトリです。
- 検出されたリポジトリのうち、どれを修正するか、またマイナー/メジャーアップグレード、ベース OS の変更、アプリケーションコードの変更が見込まれるものについての承認。
- 対象を検証してビルドを実行するために必要なレジストリ、パッケージミラー、CI へのアクセス。
手順
- クローンする前に、Git ホストのコード検索を使って、アクセス可能なすべてのリポジトリを読み取り専用で検索します(コード検索がない場合、GitHub Enterprise Server やセルフマネージドの GitLab ではよくあります。浅いクローンを作成し、
rg -n --hidden --glob '!.git'を実行してください)。以下を探します。php:イメージおよびその他の PHP ベースイメージ。php*OS パッケージ(apt/apk/dnf)、setup-phpCI ステップ、PHP ソースのダウンロードと./configureによるビルド。- PHP をインストールする Helm、Kustomize、Terraform/Packer、Ansible/Chef/Puppet のコード。
- 使用状況を示すシグナルとしての
composer.json/composer.lockおよび*.php。 - リポジトリのテストコマンド、および対象のマイナーバージョンで破損することがわかっているコード(例:8.2 では未宣言/動的プロパティ、
${}による補間、utf8_encode)。これにより、アップグレードのリスクをゲートで示せます。
- 1 つのインベントリ表を作成します。項目は、リポジトリ、ファイル:行、シグナル、現在のバージョン、チャネル(公式イメージ、ディストリビューションのパッケージ、ソースビルド、マネージドプラットフォーム)、固定/浮動/ダイジェスト固定、SAPI、判別できる場合はインターネットへの公開状況、テストカバレッジ(なし、薄い、スイート)、確信度です。検索できなかったリポジトリは別に一覧表示します。
- 各項目に修正済み、脆弱、不明のいずれかを付けます。ディストリビューションおよびマネージドプラットフォームのビルドについては、ベンダーのパッケージ変更履歴またはアドバイザリで両方の CVE を確認します。
php -vと上流のバージョン番号を比較して判断してはいけません。 - ここで停止します。表を提示して、どのリポジトリにパッチを適用するか尋ねます。同じメッセージで、マイナー/メジャーアップグレード、ベース OS の変更、想定されるアプリケーションコードの変更についても尋ね、すべて事前に承認できるようにします。調査中は何も変更しません。
- 承認されたリポジトリを 1 つずつ処理します。エージェントがサブエージェントに対応している場合は、リポジトリごとに 1 つ起動し、同時実行は最大 5 つにします。編集前に、そのリポジトリのインベントリを再確認します。
- 各リポジトリでは、パスごとに最小の修正済みターゲットを選び、編集前にそれが存在することを確認します。パブリックホストにアクセスできない場合は、リポジトリの CI がすでに使用しているレジストリまたはパッケージミラー(Artifactory、Nexus、Harbor、クラウドレジストリ)で確認します。どちらにもアクセスできない場合は、PR でターゲットを未検証と明記し、CI ビルドで確認します。
- 固定イメージタグ:同じマイナーバージョンの修正済みパッチに更新し、バリアント(
-fpm、-apache、-alpine、-bookwormなど)は維持します。 - ダイジェスト固定:新しいダイジェストを解決して固定します。
- 浮動タグ:タグは変更しません。
--pull --no-cacheによる再ビルドと再デプロイを必須とし、検証したプラットフォームごとのダイジェストを記録します(タグが再プッシュされるとインデックスダイジェストは変わります)。タグのベース OS が移行している場合(例:bookworm → trixie)は、その旨を明記します。 - プレースホルダーまたは解決できないダイジェスト:実際にデプロイされているものが不明なため、その旨を記載し、実行中のイメージをユーザーに確認します。
- ディストリビューションのパッケージ:ベンダーのセキュリティリポジトリからアップグレードし、パッケージのリリースと変更履歴の CVE エントリを記録します。Dockerfile では修正済みリリースを固定するか、それより古いものがインストールされている場合はビルドを失敗させます。Ansible/Chef/Puppet では、
state=present(または同等の設定)だけでは既存ホストはアップグレードされません。latestまたはバージョンを固定してから、PHP を再起動します。 - CI の
setup-php:major.minorを指定し、ランナーが取得できる最新パッチをインストールするため、major.minorを設定し、CI ログでパッチを確認します。 - ソースビルド:修正済み tarball に切り替え、php.net の SHA-256 を検証し、configure フラグと拡張機能は維持します。7.4/8.0/8.1 では、代わりに PHP が公開しているバックポートコミットを使います(コミットハッシュを固定。tarball のチェックサムはありません)。または、承認を得て、サポート対象ブランチに切り替えます(手順 8)。
- Helm/IaC:アーティファクトを実際に選択している入力(イメージタグ/ダイジェスト、AMI、パッケージの固定値)を変更し、ロックまたはレンダリング済み出力を再生成します。
- 固定イメージタグ:同じマイナーバージョンの修正済みパッチに更新し、バリアント(
- Composer の
require.phpとconfig.platform.phpは変更しません。これらはデプロイされるランタイムを選択するものではありません。 - PHP 8.1 以前は別扱いで報告し、ベンダーがサポートするビルド(例:ベンダーパッケージで修正される Ubuntu jammy の 8.1)と、サポート対象外のもの(ソースビルド、EOL イメージ)を区別します。ベンダーのバックポートまたは PHP のバックポートという選択肢に加え、サポート対象ブランチへのアップグレードパスを提示します。マイナー/メジャーアップグレードは、ユーザーの承認がある場合のみ行います。
- 変更の前後に、リグレッションをテストします。
- ベースライン:編集前に、現在のアーティファクトをビルドして(
--pullを指定し、ロールバック先としてダイジェストを記録)、その中でリポジトリのテスト(composer test、PHPUnit/Pest、make test、または CI のテストコマンド)を実行します。公式のphp:イメージには Composer が含まれていません。スクリプトの基盤となるコマンドを実行するか、Composer だけを追加したスクラッチイメージを使います。結果を記録し、既存の失敗をアップグレードのせいにしないようにします。 - 変更後:再ビルドし、新しい本番イメージの中で同じテストを実行します。ホスト上では実行しません。そのイメージにテストまたは開発依存関係が含まれていない場合は、同じベースからテストステージをビルドするか、テストをマウントします。新たな失敗、エラー、新たな非推奨警告はリグレッションとして扱います。
- ランタイムの比較:旧イメージと新イメージの
php -mおよび主要なphp -i値(ini 設定、ICU/OpenSSL/libxml のバージョン)を差分比較し、拡張機能、ini、ベース OS の変更を報告します。 - スモークテスト:本番環境と同じ方法でコンテナを起動し(FPM/Apache/CLI のエントリーポイント)、ヘルスチェックまたはメインルートにリクエストを送り、ログに致命的エラーや非推奨警告がないか確認します。レスポンスボディとヘッダーも確認します。
display_errorsが有効な場合(php.ini がないイメージではデフォルトで有効)、新たな非推奨警告がページに出力され、JSON レスポンスやヘッダーが壊れることがあります。 - マイナー/メジャーアップグレード(例:8.1 → 8.2)では、新しいイメージ内で
composer check-platform-reqsも実行します(composer.lockがない場合は、先にスクラッチコピー内で生成します)。さらに PHPCompatibility(phpcs --runtime-set testVersion)または Rector のドライランを実行し、該当する UPGRADING の注意事項を列挙します。8.2 より前の安定版が使われているため、ターゲット PHP バージョンを設定した Rector を優先します。これらの静的ツールでは動的プロパティなどの実行時の非推奨警告を検出できないため、テストやスモークテストの代わりにはなりません。新しいイメージ自体による拡張機能の変更(例:8.2 以降の公式イメージではftpが削除されたこと)も報告します。 - 各ステップの出力をログ(ベースライン、変更後、ランタイム差分、スモーク)として保存し、PR に添付します。
- リポジトリにテストがない(または少数しかない)か、ビルドできない場合は、そのことを目立つ形で明記します。不足しているものだけを追加したスクラッチコピーで検証し、最小限のスモークテストまたは特性テストを提案します(承認なしではコミットしません)。
- アーティファクトのバージョンを確認します(
php -v/php-fpm -v、またはイメージ SBOM)。ディストリビューションのビルドでは、インストールされたパッケージのリリースに修正が含まれていることも確認します。 - リグレッションが発生した場合は、上記の読み取り専用チェックを完了してから停止し、失敗した出力と、スクラッチコピーで検証済みの最小限の修正を報告します。ユーザーが判断するまで、バージョン更新はコミットせずに残します。承認なしにアプリケーションコードを変更しません。
- ベースライン:編集前に、現在のアーティファクトをビルドして(
- リポジトリごとに焦点を絞った PR を 1 つ作成します。各パスの変更前 → 変更後、ダイジェスト、再ビルドが必要な浮動タグ、ブロックされた項目、EOL 項目、変更前後のテスト結果、ランタイム差分、検証根拠を記載します。リスクを、同じベースでのパッチ更新は低、マイナー/メジャーアップグレード、ベース OS の変更、未テストのリポジトリは高として表示し、カバレッジが薄い場合はその旨も記載します。段階的な展開計画を含めます。まずステージングまたはカナリアに展開し、次にロールバック先の以前のイメージダイジェスト/パッケージバージョンを示します。このロールバック先には依然として脆弱性があるため、以下の一時的な緩和策と組み合わせます。
- リポジトリごとの結果を 1 つの表にまとめます。項目は、リポジトリ、PR、パス、変更前 → 変更後、修正の根拠、テスト、ブロックされた項目、フォローアップです。修正が有効になるのは、すべてのワーカーをデプロイして再起動した後であることをユーザーに伝えます。
仕様
- 調査は読み取り専用で行い、明示的な承認ゲートで終了します。
- 編集前に、各対象が存在し、修正を含んでいることを確認します。
- 各 PR には、ビルド済み成果物に対する検証と、イメージ内で実施したテスト結果の修正前と修正後の比較を含めます。
- 完了とは、承認されたすべてのデプロイが修正済みと検証されるか、具体的な次の手順を添えてブロック中と報告されている状態です。
アドバイスと参考情報
- 修正済みの既知のバックポート(記載されていないリリースについては、Debian trixie や Ubuntu php8.5 などのベンダートラッカーを確認してください):
- Debian bookworm
8.2.35-1~deb12u1。 - Ubuntu noble
8.3.6-0ubuntu0.24.04.13。 - Ubuntu jammy
8.1.2-1ubuntu2.28。
- Debian bookworm
- remirepo.net では同日中の更新はありませんでした。代わりにディストリビューションのパッケージまたはソースからのビルドを推奨します。
- 一時的な緩和策は、リスクを低減するだけです。
session.upload_progress.enabled=0を php.ini または FPM プールに設定し(ini_set()や.user.iniでは設定しないでください)、すべてのワーカーを再起動します。- 8.5 では、
fatal_error_backtraces=0を設定します。 - アップロードがない場合は
post_max_sizeを 8M に、アップロードがある場合は 32M に設定します。 - プロキシで、ボディサイズ、フィールド数、マルチパートのパート数、ヘッダー数、ネストの深さを制限します。
memory_limit=-1を設定し、コンテナー/cgroup のメモリー制限と組み合わせます。
- PHP を組み込んでいるアプライアンスやベンダー製品には、ベンダーによる更新が必要です。対象としてフラグを立て、製品に直接パッチを適用しないでください。
- 8.5.12 の修正が不完全だという未検証の主張が oss-security で広まりました。ロールアウト前に PHP のアドバイザリー(GHSA-w8hw-w9fx-j79w、GHSA-6wmf-4rv5-p3rp)を確認し、更新がないか調べてください。
禁止事項
- ユーザーがリポジトリを承認する前に編集しないでください。
- イメージタグ、ダイジェスト、パッケージバージョンを推測しないでください。
- 緩和策を修正として提示しないでください。
- 緩和策として
RLIMIT_ASまたはRLIMIT_DATAを使用しないでください。これらは脆弱なアロケーション失敗を引き起こします。 - 変更について明示せずに、SAPI、ベースディストリビューション、イメージの種類、拡張機能、ビルドフラグを変更しないでください。
コメント
Markdown 対応