何が起きたか・対象
ComposerはPHPプロジェクトの依存パッケージを取得・管理します。利用者がプロジェクトの依存を更新する際や、Packagist側が登録パッケージの情報を取得する際に、GitやMercurialのリポジトリを処理します。攻撃者がそのリポジトリの設定やブランチ名を操作できると、ファイルを読むための対象名を、呼び出すツールのオプションとして扱わせる場合がありました。
Composerが外部リポジトリからファイルを読む際、作成者が決めるファイル名や識別子をGit・Mercurialへ渡す処理に、引数注入の問題がありました。識別子はCVE-2022-24828です。
攻撃者がcomposer.jsonのreadmeやブランチ名を操作し、Composerがそのリポジトリを処理すると、値はVcsDriver::getFileContent()のfileやidentifierへ入り、版管理ツールへ渡ります。ツールが値を単なる対象名でなく別の動作を指示する引数として解釈すると、Composerを起動した環境で意図しない命令が動くおそれがありました。
影響は実行ユーザーの権限に従います。説明用に、命令がビルド環境の資格情報を読み外部へ送れるなら攻撃者が取得できますが、資料が全利用者の秘密窃取を観測したという意味ではありません。修正の検査と引数区切りは差分を確認していますが、各経路の全ての実行用オプションを再現したものではありません。
例えばgetFileContentのfileは取得するファイル名、identifierは取得元のブランチなどです。composer.jsonのreadme欄はREADME本文ではなく、そのファイル名を指定します。Mercurial経路ではこの値がfileへ入り、ブランチなどの指定はidentifierへ入ります。先頭が-の値を拒否しなかったことが、対象名を操作オプションへ変える原因でした。
報告・修正・公開の時系列
2022-04-13に開発元が公表しました。初回修正版は1.10.26、2.2.12、2.3.5です。Packagist.orgとPrivate Packagistは報告から一日以内に修正したと説明されています。
正常ならどう動くはずだったか
Composerがリポジトリからファイルを取得するとき、composer.jsonのreadmeやブランチ名などは、読む対象を指定するデータです。リポジトリの作成者がその値を決めても、GitやMercurialへ別の動作を指示する引数として採用してはいけません。
技術的な原因
getFileContentは、Gitではgit show、Mercurialではhg catを起動してファイル内容を取得します。Mercurialの修正前はhg cat -rに版の指定とファイル名を続けていました。外部値が先頭-のオプションなら、ツールがファイル名としてではなく動作の指定として解釈する場合があります。
無害な仕組みの例では、ファイル名として渡した--helpがヘルプ表示の指定になれば、内容取得という目的から外れます。実際の問題は、呼び出し先が持つコマンド実行につながる機能も外部値で指定できることです。開示は任意コマンド実行を報告していますが、各ドライバでの実行用オプションの組合せを本記事では網羅していません。
シェル向けに引用して一つの引数にしても、GitやMercurialはその引数を自分のオプションとして解釈します。この問題では、入力の中のシェル記号を動かす経路と、呼び出し先ツールの機能を選ばせる経路を区別する必要があります。
攻撃が成立する条件と流れ
攻撃者がcomposer.jsonのreadmeや、プロジェクトへURLで明示登録されたGit・Mercurialリポジトリのブランチ名を操作します。Composerがそのリポジトリのファイルを取得すると、値がfileやidentifierを経て版管理ツールへ渡ります。ツールが想定外の引数として解釈することで、Composerを実行した環境で命令が動くおそれがありました。 Composer自体をブランチ名で狙う経路では、利用者のプロジェクトのcomposer.jsonに、そのGit・MercurialリポジトリがURLで明示登録されていることが条件です。readme経路はComposerを組み込むPackagistなどの処理として開示されており、同じ登録条件を全経路へ一律に当てはめません。
確認された事実と、想定される影響
開発元は任意コマンド実行を可能な影響として報告しています。説明用の例では、その命令がビルド環境で読める資格情報を読み、攻撃者のサーバーへ送信できると、攻撃者が秘密を入手します。公開用ファイルへ書ける場合は、そのファイルを変更して後の配布内容を変えるおそれもあります。
これらの被害範囲はComposerを実行するユーザーの権限、渡される秘密、外部通信や後続の配布処理に依存します。開発元は公表時点で実悪用を把握していないとしましたが、全ての時点で悪用がなかったという意味ではありません。
実際の修正・対応方針
開示された修正版は1.10.26、2.2.12、2.3.5です。確認した修正コミットでは、GitとMercurialのidentifierが先頭-なら拒否し、ブランチ一覧でも同様の値を除外しています。Mercurialのファイル名の前には--を置き、それ以後をオプションではなく対象名として扱うようにしています。利用する系列の現行サポート状況も確認します。
利用者・運用者が確認すること
サポートされる修正版へ更新し、明示登録する外部リポジトリやビルド実行権限を確認します。ビルド環境に不要な秘密を置かないことも、コマンド実行が起きた場合の取得範囲を狭めます。
開発者への教訓(教材としての考察)
「一つの値として安全に渡す」と「その値で危険な機能を選べない」は別です。呼び出す側の文字列処理と、呼び出されるツールの引数の意味を両方確認します。
出典・確認範囲
- [1] Missing input validation can lead to command execution via VcsDriver::getFileContent()Composer / 確認日 2026-10-29
- [2] Fix VcsDriver argument injection (2c40c53)Composer / 確認日 2026-11-01
参照資料では実悪用や実際の被害件数を確認できません。未記載の実装差分は推測していません。