CVSS: 8.8 High(CVE-2026-40261, AV:N)/7.8 High(CVE-2026-40176, AV:L)
影響: Composer
2.0〜2.2.26(LTS)・2.3〜2.9.5(mainline)修正版:
2.2.27(LTS)・2.9.6以降(mainline、2.9.7でregression fix追加)CWE: CWE-20(入力検証不備)・CWE-78(OSコマンドインジェクション)
報告: kodareef5・Saku0512 /公開: Seldaek(Jordi Boggiano)/日時: 2026-04-14
PHPのデファクトパッケージマネージャ「Composer」に2件の重大なコマンドインジェクション脆弱性が発見された。Composer内部の Perforce VCSドライバコード(src/Composer/Util/Perforce.php)でシェルコマンドを構築する際に入力エスケープが抜けており、悪意ある composer.json やリポジトリメタデータから任意コードが実行される。
🔍 混同注意: 本CVEは Composerに同梱されているPerforce連携ドライバ の脆弱性であり、Perforce社が提供する Perforce Helix Core(P4)サーバー自体 の脆弱性(例:CVE-2023-45849など)とは別物です。つまり「Perforceサーバーを運用しているか否か」は関係なく、PHP開発者が使うComposer本体に存在するシェルインジェクションの問題です。実際、GHSAには「Perforceがインストールされていなくても悪用可能」と明記されています。
特に CVE-2026-40261(CVSS 8.8、ネットワーク攻撃可) は深刻だ。攻撃者が用意したComposerリポジトリからパッケージをインストールするだけで、ローカルマシンに Perforceがインストールされていなくても 任意コマンドが走る。--prefer-source オプション使用時や dev-prefix バージョン(dev-main 等)のインストール時が特に危険な状況だ。
本脆弱性はGitHub Security AdvisoriesにGHSA-gqw4-4w2p-838qおよびGHSA-wg36-wvj6-r67pとして公開され、メンテナのJordi Boggiano(Seldaek)自身が即日パッチ版2.2.27/2.9.6をリリースした。発見者はkodareef5とSaku0512の両セキュリティ研究者。
現時点でLaravel、Symfony、WordPress等の主要パッケージが本脆弱性を悪用するよう改ざん・再公開されたという報告は確認されていません。これらのパッケージは自身の
composer.json で Perforce source type を使用していないため、通常利用では本脆弱性のトリガーとなるコードパスに到達しません。ただし「完全に無関係」ではありません。攻撃者が新規に悪意あるパッケージを Packagist 等に公開し、あなたがそれをインストールしてしまうシナリオは理論上成立します(現時点で観測例なし)。そのため主要プロジェクトを運用中であってもパッチ適用(2.9.6以降 / 2.2.27)は推奨です。
あなたは影響を受けるか — 30秒判定
バージョン確認"] --> B{"バージョンは?"} B -->|"2.0.0 〜 2.2.26"| R1["即時対応必須
2.2.27 LTSへ更新"] B -->|"2.3.0 〜 2.9.5"| R2["即時対応必須
2.9.6 mainlineへ更新"] B -->|"2.2.27 または 2.9.6+"| S["パッチ済み"] B -->|"1.x 以前"| L["既にEOL
2.x系へ移行推奨"] R1 --> U["composer self-update --2.2"] R2 --> U2["composer self-update"] style R1 fill:#f8d7da,stroke:#721c24 style R2 fill:#f8d7da,stroke:#721c24 style S fill:#d4edda,stroke:#28a745
この記事ではセキュリティに特化して解説します。AIセキュリティ全般は サプライチェーンセキュリティ完全ガイド2026|攻撃手法・防御ツール・実践チェックリスト をご覧ください。
Composer 脆弱性の技術的メカニズム|エスケープ抜けの2箇所
両CVEともComposer内部の Perforce クラスに存在するシェルコマンド組み立て処理が原因だ。
CVE-2026-40261|Perforce::syncCodeBase() のエスケープ抜け
Perforce::syncCodeBase() メソッドが $sourceReference パラメータを エスケープせずにシェルコマンドへ連結 していた。source.reference フィールドは本来、Perforceのチェンジリスト番号やラベル名が入る想定だが、そこにシェルメタ文字(;・&・バッククォート・$() など)を入れられる。
公式advisory本文(Seldaek記述):
The
Perforce::syncCodeBase()method appended the$sourceReferenceparameter to a shell command without proper escaping, allowing an attacker to inject arbitrary commands through a crafted source reference containing shell metacharacters.
致命的なのは「Perforceがインストールされていなくても攻撃が成立する」点だ。Composerは構築したコマンドを実行しようとするため、Perforceバイナリがローカルに存在するかどうかは関係ない。シェルに渡された時点で任意コマンドが走る。
CVE-2026-40176|Perforce::generateP4Command() の接続パラメータ注入
こちらは Perforce::generateP4Command() メソッドが Perforce接続パラメータ(port・user・client) を補間する際にエスケープを行っていない問題。composer.json の repositories 配列にPerforce型リポジトリを書き込み、そのportやuserフィールドにシェルコマンドを混入できる。
こちらはVCS repositoriesが root composer.json または設定ディレクトリ(~/.config/composer/composer.json)からしか読まれない仕様により、依存パッケージ経由では悪用不可という限定がある。代わりに、攻撃者が作ったプロジェクトに含まれる composer.json を実行するケースで発動する。
攻撃シナリオ|悪意あるパッケージメタデータから composer install 一発でRCE
CVE-2026-40261の攻撃フローは以下のように成立する。
(PHP開発者/CI) participant S as 被害者のシェル A->>R: perforce型ソースで
悪意あるreference/urlを
含むパッケージ公開 V->>R: composer require
または composer install
(--prefer-source) R-->>V: package metadata
(悪意ある source.reference) V->>V: Perforce::syncCodeBase()
がコマンド構築 V->>S: 未エスケープの
シェルコマンド実行 S-->>V: 任意コード実行
(Perforceバイナリ不要) Note over V,S: マシン乗っ取り成立
攻撃の現実的な発動条件:
--prefer-sourceを明示指定している- dev-prefixバージョン(
dev-main・dev-masterなど)をインストール preferred-install: sourceを設定ファイルで指定している
dev-prefixバージョンは デフォルトでsourceが優先されるため、開発中のPHPプロジェクトでは非常に多くのユースケースで攻撃面が開いている。
Composer RCEで攻撃者が実際にできること|任意コマンド実行の現実的な被害範囲
公式GHSAはRCE成立時の挙動を 「command execution in the context of the user running Composer」(Composerを実行したユーザーと同じ権限でシェルコマンドを任意実行)と明記している。CVSS Scope は S:U(Unchanged)のため権限の自動昇格はないが、開発者ユーザーの権限で読めるものはすべて読まれ、書けるものはすべて書き換えられると想定すべきだ。
⚠️ 本記事執筆時点(2026-04-14 20時JST、advisory公開約3時間後)で公開PoCは確認されていない。以下は「任意コード実行が成立したRCEが過去どう悪用されてきたか」に基づく想定被害であり、本CVEで実際に観測された攻撃ではない。
開発マシンで想定される悪用パターン
任意コマンド実行が走ると、Composerを実行したユーザー権限でアクセスできる資産はすべて攻撃対象になる。以下は過去の同種RCE事例で実際に起きてきた悪用パターン:
| 悪用カテゴリ | 具体的な被害 | 根拠となる過去事例 |
|---|---|---|
| 認証情報の窃取 | ~/.ssh/id_rsa・~/.aws/credentials・~/.gitconfig・.npmrc・.git-credentials を外部サーバに送信 |
Codecov Bash Uploader事件(2021) |
| ブラウザデータ窃取 | Chrome/Firefoxのログイン情報DB・Cookieを抽出 | 各種info-stealerマルウェア |
| 永続化(バックドア) | cron・launchdデーモン・.zshrcへの追記で再起動後も常駐 |
event-streamインシデント(2018) |
| 暗号資産マイナー設置 | バックグラウンドで採掘プロセス常駐・CPU占有 | 過去多数のnpm/Composer系インシデント |
| 横展開の足がかり | 社内ネットワークのスキャン・他サーバへの認証試行 | SolarWinds型サプライチェーン攻撃 |
開発者マシンは 本番クラウドへのアクセス権限を持つ ことが多いため、一度RCEが成立すると本番環境侵害に直結するケースが多い。特にAWSプロファイルが複数設定されている環境は要注意。
CI/CD環境でやられるとさらに深刻
CI/CDは「開発者マシンより権限が強い」ケースが多く、被害が跳ね上がる:
- GitHub Actionsシークレット漏洩: 環境変数
GITHUB_TOKEN・NPM_TOKEN・デプロイキー・AWS STS認証がすべて読み出される - 本番デプロイ経路の悪用: CIから本番サーバへのSSH秘密鍵が格納されていれば、そのまま本番侵入
- 他社へのサプライチェーン汚染: あなたの会社のパッケージやSaaSのビルドパイプラインに悪意あるコードを埋め込み、顧客先にも被害拡散(2026-04-11のOpenAI axios侵害事件がまさにこの型)
想定される攻撃文字列の形
公式PoCは未公開だが、GHSA記載の「source reference with shell metacharacters」という表現から、攻撃者が仕込む composer.json の構造は以下のような形と想定される(あくまで仕組みの説明のための例示):
{
"repositories": [
{
"type": "perforce",
"url": "p4://example.com",
"depot": "example",
"branch": "main"
}
],
"require": {
"example/package": "dev-main"
}
}
Composerが Perforce::syncCodeBase() 内で組み立てる p4 sync //...@$reference や、Perforce::generateP4Command() で組み立てる p4 -p $port -u $user -c $client ... の各パラメータにシェルメタ文字が入ると、セミコロンやバッククォート以降が別コマンドとしてシェルに渡る。この構造は過去の CVE-2021-29472(Composer Mercurial RCE)や CVE-2024-35241(Composer git branch injection) と同じパターンだ。
ユーザー操作は必要(「0クリック」ではない)
CVSSベクトルは両CVEとも UI:R(User Interaction Required)——つまり攻撃者だけで被害は発生せず、被害者が以下いずれかの操作を行う必要がある:
composer install・composer update・composer requireを実行する- CI/CDで自動的に上記が走るトリガー(push・PR・scheduled job)が発火する
この「UIが必要」という条件は実効的にはほぼ意味がない——PHP開発者は毎日のように composer install を打つし、CIも自動で走る。攻撃者から見れば「悪意あるパッケージをPackagistや独自リポジトリに上げておく → あとは時間が解決する」という状況だ。
Composer CVE-2026-40261/40176 の比較|どう違うのか
| 項目 | CVE-2026-40261 | CVE-2026-40176 |
|---|---|---|
| 脆弱メソッド | Perforce::syncCodeBase() |
Perforce::generateP4Command() |
| CVSS 3.1 | 8.8 High | 7.8 High |
| 攻撃ベクトル | Network (AV:N) | Local (AV:L) |
| 攻撃面 | 悪意あるパッケージリポジトリ | 悪意ある composer.json |
| 依存経由悪用 | ✅ 可能(任意リポジトリ配信で) | ❌ 不可(rootのcomposer.jsonのみ) |
| トリガー条件 | --prefer-source または dev-prefix |
悪意あるプロジェクトでComposer実行 |
| Perforceバイナリ要否 | 不要(注入成立するだけで発火) | 不要 |
| 発見者 | kodareef5 | Saku0512 |
CVE-2026-40261の方が 攻撃範囲が広く深刻度も高い。Packagist(Composerの公式パッケージリポジトリ)外のカスタムリポジトリを利用している企業や、プライベートレジストリ運用中の組織は特に注意が必要だ。
PHP Composerセキュリティ対応チェックリスト|今すぐやるべきこと
本CVEの影響範囲は「Composerを使うPHPプロジェクト全部」と広範のため、開発者個人・CI/CD担当・本番運用・セキュリティ管理者の立場別に必要な対応を整理する。以下のチェックリストを順に潰していけば、組織として必要な措置がすべて完了する。
✅ Phase 1: 今すぐ(5分以内)— 開発マシンの更新
全PHP開発者が最初に実行する項目。手元のComposerが脆弱版かを確認し、即座にパッチ版へ更新する。
# 1. 現在バージョン確認
composer --version
# 例: "Composer version 2.9.5 2026-02-15 XX:XX:XX" ← 脆弱
# 2. mainline系なら最新に
composer self-update
# 2.2 LTS系を固定運用している場合
composer self-update --2.2
# 3. 更新後の再確認(2.9.6以降 または 2.2.27 が表示されればOK)
composer --version
5分以内にできる作業です。後回しにしないこと。dev環境で composer install を走らせる予定がある人は、更新前に絶対にコマンドを実行しないでください。
💡 2.9.7について: 2026-04-14 11:36 UTC(2.9.6の約2時間後)にリリース済み。セキュリティ修正ではなく、2.9.6に混入した軽微なregression(「Composerコマンドのサブストリングと同名のスクリプトエイリアスが呼べない」問題 #12802)を修正する純粋なバグフィックス。セキュリティの観点だけなら2.9.6で十分だが、カスタムスクリプトを多用するプロジェクトは 2.9.7以上が推奨。
✅ Phase 2: 今日中(1時間以内)— CI/CD・Docker環境の更新
ローカル環境だけでなく、CI/CD・本番デプロイパイプラインで動くComposerも同じく脆弱。こちらは「一斉更新」が必要になる。
2-1. GitHub Actions / setup-php の更新
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- tools: composer:2.9.5
+ tools: composer:2.9.6
バージョン指定をしていない場合(tools: composer のみ)は最新版が引かれるため自動的に2.9.6となる。ただしDockerイメージ経由の場合はキャッシュされた古い版が使われ続けるので、次の項目も実行すること。
2-2. Docker イメージ経由のComposerを更新
# Before(脆弱)
FROM composer:2.9.5
# または
FROM composer:2
# After(推奨)
FROM composer:2.9.6
# もしくはタグなしで常に最新
FROM composer:latest
既存のDockerビルドキャッシュに古いComposer版が入っている可能性があるため、--no-cache でリビルドしてから本番デプロイすること。
docker build --no-cache --pull -t myapp:latest .
2-3. 本番/ステージングサーバー上のComposer更新
本番サーバー上で composer install --no-dev を実行するタイプのデプロイをしている場合、サーバー上のComposer自体を更新する必要がある。
# サーバーへSSH後
sudo composer self-update
# またはrootで走らない運用なら
composer self-update --install-dir=/usr/local/bin
composer --version # 2.9.6 または 2.2.27 を確認
Ansible・Chef・Terraformなどで管理している場合は、プロビジョニングスクリプトのComposerバージョンピンも同時に更新すること。構成管理ツールが古い版を再度インストールして上書きしてしまう事故を防ぐ。
✅ Phase 3: 今週中(数日以内)— 監査と予防策の恒久化
直近の攻撃可能性を監査し、再発防止策をプロジェクトに組み込む。
3-1. composer.json / composer.lock の棚卸し
perforce タイプのリポジトリ定義が含まれていないかをgrepで確認する。Perforceを使っていない組織は本来入っているはずがないため、もし見つかれば既に何かが仕込まれている可能性がある。
# プロジェクト全体で perforce 型リポジトリを探す
grep -rn "\"type\": *\"perforce\"" . --include="composer.json"
# ソース設定の不審な値もチェック
grep -rn "\"source\":" . --include="composer.json" | grep -Ei "perforce|p4"
3-2. preferred-install: dist を恒常設定化
Composerを最新版に保っても、将来類似の脆弱性が出たときにsource優先設定だと攻撃面が開いたままになる。「VCSからsourceでダウンロードする必要性がない」プロジェクトは、dist優先を設定ファイルに書き込むのが正攻法。
{
"config": {
"preferred-install": "dist"
}
}
または全プロジェクト共通の設定として:
composer global config preferred-install dist
3-3. カスタムComposerリポジトリの信頼性確認
Packagist公式以外の カスタムリポジトリ(企業内Satis・Private Packagist・GitLab Package Registry等)を使っている場合、そのインフラの侵害が即RCEに直結する。以下を確認:
- カスタムリポジトリの認証とアクセス制御
- パッケージメタデータに書き込み可能な権限者のリスト
- 最終更新日時ログの監査
3-4. CI/CDにcomposer auditを組み込む
Composer 2.4以降には composer audit コマンドが搭載されている。GHSA連携で既知脆弱性を検知できる。
# .github/workflows/ci.yml に追加
- name: Composer audit
run: composer audit --no-dev --format=json
これで今後同様の脆弱性が公開された時、CIが自動的に警告を出すようになる。
✅ Phase 4: セキュリティ管理者向け — 組織通達と検知
セキュリティチーム・CTO・開発リードは、以下の社内通達と監視体制を整備する。
4-1. 社内通達テンプレート
Slack・社内Wiki・メールで以下のテンプレートを展開:
【至急】PHP Composer脆弱性対応(CVE-2026-40261/40176)
■ 影響: Composer 2.0〜2.2.26 および 2.3〜2.9.5
■ 対応期限: 本日中
■ 作業:
1. 各自の開発機で `composer self-update` を実行
2. 2.9.6 または 2.2.27 になっていることを確認
3. CI/CD・Dockerイメージを更新してデプロイ
■ 緊急回避策(更新できない場合):
`composer install --prefer-dist` を使う
■ 参考: https://github.com/composer/composer/security/advisories/GHSA-gqw4-4w2p-838q
4-2. 検知ルールの設定
シェル実行ログやEDR/XDRで、以下のパターンが出た場合は攻撃試行の可能性がある:
- Composerプロセスから予期せぬ子プロセス(
sh -c・bash -c・curl・wget等) composer install実行直後のネットワークアウトバウンド増加composer.jsonのrepositoriesフィールドに"type": "perforce"を含むコミット
4-3. パッケージ管理プロセスの見直し
今回の事件を機に、組織として以下を再点検:
- 未検証のライブラリを
composer requireしない運用ルール - PR時に
composer.json・composer.lock変更の人間レビュー必須化 - Dependabot・Renovateによる自動監視の有効化
Composer 脆弱性の緊急回避策|すぐ更新できない場合の一時しのぎ
どうしても即座に更新できない事情がある場合(変更凍結期間中・レガシー環境の制約等)は、以下のワークアラウンドで攻撃面を縮小できる。ただし根本解決ではないため、できるだけ早くComposer自体の更新に切り替えること。
# インストール時にdistを強制(sourceによる脆弱コード実行を避ける)
composer install --prefer-dist
# 既にstate restored済みのcomposer.lockがある場合も
composer update --prefer-dist
設定ファイルに書く場合:
{
"config": {
"preferred-install": "dist"
}
}
公式advisoryのWorkaroundsには「信頼できるComposerリポジトリのみを使用する」とも記載されているが、これは補助的な対策に過ぎないことに注意。過去にはPackagist公式自体がサプライチェーン攻撃の対象になった事例(2021年のAPIトークン問題、2022年のctx/PHPass乗っ取り等)があり、「信頼できるリポジトリなら絶対安全」は成立しない。また正規リポジトリに正規ユーザーとして公開された個別パッケージが悪意を持つ可能性も排除できない。最終的な根本解決は必ず パッチ適用(2.9.6以降 / 2.2.27) で行うこと。
関連CVEと最近のサプライチェーン攻撃|PHPエコシステムの現在地
2026年に入り、開発ツール・パッケージマネージャ系のCVEが加速している。直近の大きな事例:
- 同日(2026-04-14): Axios CVE-2026-40175(CVSS 10.0)— プロトタイプ汚染からRCEが公開されたばかり
- 2026-04-11: OpenAI axios開発者ツール侵害事件 — 3月のnpm汚染がOpenAI社内ビルドまで波及
- 2026-04-09: Docker CVE-2026-34040(認可バイパス)
- 2026-04-04: GitHub GlassWorm サプライチェーン攻撃
「開発者マシン/CIを攻撃面として狙う」攻撃が2026年Q1から明確に増加している。Composer・npm・Dockerという「毎日動くツール」の脆弱性は、直接ユーザーを攻撃するよりも広い被害を引き起こし得るため、開発者側の脆弱性監視・即時パッチ適用が今後さらに重要になる。
関連記事: サプライチェーンセキュリティ完全ガイド2026|攻撃手法・防御ツール・実践チェックリスト
まとめ|全PHP開発者は今すぐ composer self-update
今回のCVE-2026-40261/40176は、Composerというデファクトツールに存在した典型的なコマンドインジェクション脆弱性だ。特にCVE-2026-40261は Perforce未インストールでも発火する・ネットワーク経由で悪用可能・CVSS 8.8 という3拍子が揃っており、PHP開発者全員が影響対象となる。
幸い、メンテナのJordi Boggiano(Seldaek)は同日に修正版2.2.27/2.9.6をリリース済みだ。更新作業は composer self-update 一行で完了する。CI/CDイメージも合わせて更新し、緊急回避策として --prefer-dist を併用すれば、現実的な攻撃リスクをほぼ封じ込められる。
参照ソース
- GHSA-gqw4-4w2p-838q(CVE-2026-40261)- Composer公式アドバイザリ
- GHSA-wg36-wvj6-r67p(CVE-2026-40176)- Composer公式アドバイザリ
- composer/composer v2.9.6 Release Notes
- composer/composer v2.9.7 Release Notes — 2.9.6のregression fix
- composer/composer v2.2.27 Release Notes
- Composer公式: Command Line Usage
- SecurityOnline: Composer Perforce Remote Command Injection