A specially crafted composer.json was all it took. CVE-2021-41116 is a code execution vulnerability in Composer, the dependency manager used by virtually every modern PHP application, caused by unsafe handling of the config.platform setting when Composer generates its runtime platform-check file. If a project pulled in a malicious or tampered manifest and someone ran a routine composer install or composer update, attacker-controlled data could end up executing as PHP the moment the application's autoloader was loaded — turning a dependency-resolution feature into an arbitrary code execution primitive.
For a supply chain security team, this is the textbook case of why manifest files deserve the same scrutiny as source code: nobody expects composer.json, a declarative config file, to be a code execution vector.
What Is CVE-2021-41116?
Composer lets developers override the PHP version and extensions it "sees" during dependency resolution using the config.platform block in composer.json. This is a legitimate feature — it's useful when you're resolving dependencies on a machine that doesn't match your production PHP version, or when you intentionally want to pin resolution against a specific runtime.
To enforce that the platform assumptions made at install time actually hold at runtime, Composer generates a small file, vendor/composer/platform_check.php, which is automatically required by the autoloader (vendor/autoload.php). That file checks the running PHP version and loaded extensions against what was assumed during dependency resolution, and throws a fatal error if there's a mismatch.
The vulnerability tracked as CVE-2021-41116 lived in how that generated file was built. Values pulled from config.platform and related version constraints were interpolated into the generated PHP source without sufficient validation. A crafted platform version string could break out of the expected literal and inject arbitrary PHP into platform_check.php. Because that file is executed unconditionally every time the autoloader boots, the injected code would run not just when someone typed composer install, but for every single request or CLI invocation of the application afterward — the compromise persisted silently inside a file most developers never open.
In short: a manifest field meant to describe the platform became a channel for code, and Composer, the PHP package manager millions of projects rely on for dependency and autoload management, would faithfully write and then execute that code on the developer's or CI runner's behalf.
Affected Versions and Components
CVE-2021-41116 affects Composer releases prior to the fixed versions on both maintained branches:
- Composer 1.x before 1.10.26
- Composer 2.x before 2.1.9
The vulnerable component is Composer itself — specifically the code path responsible for generating vendor/composer/platform_check.php from config.platform and package platform requirements during install, update, and autoload-dump operations. Any PHP project, library, or CI pipeline invoking an affected Composer binary against an untrusted or attacker-influenced composer.json was exposed, regardless of the application framework built on top of it. This makes the blast radius broad: the vulnerability sits in tooling, not in application code, so every project using an outdated Composer inherited the risk.
CVSS, EPSS, and KEV Context
CVE-2021-41116 was disclosed via a GitHub Security Advisory for the composer/composer repository and carries a High severity rating from NVD, reflecting the fact that successful exploitation results in arbitrary code execution — the most severe practical impact for a dependency-management tool. Exploitation does require that a victim process a malicious composer.json (for example, via a compromised package, a poisoned repository source, or a shared project file), which the scoring reflects through elevated attack-complexity and user-interaction requirements rather than a fully remote, unauthenticated path.
The flaw is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog, and there is no public evidence of widespread in-the-wild exploitation. Its EPSS (Exploit Prediction Scoring System) probability is low, consistent with a vulnerability that requires local processing of a crafted manifest rather than a network-reachable trigger. That combination — real code execution impact, but a narrower delivery path — is exactly the profile organizations tend to under-prioritize in patch queues, even though it's a legitimate supply chain foothold for an attacker who can influence a composer.json upstream (a malicious package maintainer, a compromised registry mirror, or a poisoned internal monorepo).
Timeline
- Prior to disclosure: The Composer maintainers identified and validated the platform-config code execution issue alongside two related file-permission and hostname-verification hardening fixes affecting the same codebase.
- Early October 2021: Composer released patched versions 1.10.26 and 2.1.9, closing the platform-config injection path along with the other issues fixed in that release cycle.
- October 2021: CVE-2021-41116 was published via the GitHub Security Advisory Database for
composer/composer, giving downstream consumers and vulnerability scanners a tracking identifier tied to the fixed releases. - Ongoing: Software composition analysis (SCA) tools and Linux distribution package trackers incorporated the advisory, flagging any Composer binary or
composer.pharversion predating the fix.
Remediation Steps
-
Upgrade Composer. Update to Composer 1.10.26 or later on the 1.x line, or 2.1.9 or later on the 2.x line — and ideally to the current stable release, since subsequent versions carry further hardening. Verify the installed version with
composer --versionacross all developer machines, build agents, and container images. -
Regenerate the autoload and platform-check artifacts. After upgrading, run
composer dump-autoload(or a freshcomposer install) so any previously generatedvendor/composer/platform_check.phpis rebuilt using the patched logic. -
Treat
composer.jsonas executable input. Don't runcomposer installorcomposer updateagainst manifests from untrusted sources — forks, pull requests from external contributors, or third-party packages — without review. Aconfig.platformblock with unusual or unexpected values is a signal worth a second look. -
Pin and verify your Composer binary in CI/CD. Use a known-good, checksum-verified
composer.pharor an official container image tag, and fail builds that fall back to an unpinned or outdated Composer install. -
Run
composer auditregularly. Composer's built-in audit command checks the current lockfile against known advisories; wire it into CI so a vulnerable Composer version or dependency doesn't silently persist. -
Extend scanning beyond application dependencies to the package manager itself. Vulnerability management programs often scan
composer.lockfor vulnerable packages but forget to check the Composer binary version running the install — CVE-2021-41116 is a reminder that build tooling is part of the attack surface too.
How Safeguard Helps
CVE-2021-41116 is a clean illustration of why software supply chain security has to extend past "scan the dependency tree" and into the tooling and manifests that produce your build artifacts in the first place. Safeguard is built around that broader view.
- Toolchain version enforcement: Safeguard continuously inventories the exact Composer (and other package manager) versions in use across repositories, CI runners, and container base images, flagging any instance still running a version affected by CVE-2021-41116 or similar platform config and code execution issues, well before it reaches a build pipeline.
- Manifest anomaly detection: Because this vulnerability hinged on unusual
config.platformvalues insidecomposer.json, Safeguard inspects manifest and lockfile changes for suspicious or out-of-pattern fields — including platform overrides, unexpected repository URLs, and script hooks — and surfaces them for review before they're merged or built. - Build pipeline integrity monitoring: Safeguard watches for unexpected file generation and execution during dependency installation steps, so a compromised or legacy Composer silently writing malicious code into
vendor/composer/platform_check.php(or any generated autoload artifact) doesn't slip past unnoticed. - SBOM-driven vulnerability correlation: Safeguard's software bill of materials generation captures package manager and runtime tooling versions alongside application dependencies, so advisories like CVE-2021-41116 are matched automatically against every project that touches Composer — not just the ones someone remembered to check.
- Policy gates for outdated tooling: Safeguard lets teams enforce minimum-version policies for package managers as a merge or deploy gate, converting "we should probably upgrade Composer everywhere" from a backlog item into an automatically enforced control.
CVE-2021-41116 has a fix that's been available since 2021, but "patched" and "actually running everywhere" are different states — and the gap between them is precisely where supply chain attackers operate. Safeguard closes that gap by making package manager hygiene as visible and enforceable as application dependency hygiene, so a code execution flaw in the tool that builds your software doesn't become the quiet way an attacker gets in.