CVE-2026-59944 Overview
CVE-2026-59944 is a path traversal vulnerability [CWE-22] in Composer, the dependency manager for PHP. The flaw affects versions 1.0 through 2.2.29 and 2.3.0 through 2.10.2. A malicious or compromised dependency can bypass the earlier CVE-2026-59946 binary-path hardening because Composer validates literal parent-directory segments only during dependency resolution. The symlink and installed-metadata code paths skip that validation. Composer can follow an escaping path, change the external target's permissions to world-readable and executable, and create a vendor/bin proxy pointing to that external file. The issue is fixed in versions 2.2.30 and 2.10.3.
Critical Impact
A malicious package can cause Composer to alter permissions on arbitrary local files and expose them as executable binaries through vendor/bin, enabling local privilege or trust boundary escalation during install or reinstall operations.
Affected Products
- Composer versions 1.0 through 2.2.29
- Composer versions 2.3.0 through 2.10.2
- PHP projects consuming untrusted or compromised dependencies via Composer
Discovery Timeline
- 2026-09-16 - CVE-2026-59944 published to NVD
- 2026-09-16 - Last updated in NVD database
- Fixed in - Composer 2.2.30 and 2.10.3 released with patch commits 53b8bb4c and ad649fdf
Technical Details for CVE-2026-59944
Vulnerability Analysis
CVE-2026-59944 is a symlink-following and metadata-trust flaw in Composer's binary installation logic. The earlier CVE-2026-59946 fix added checks for literal .. segments during dependency resolution. However, two later code paths, symlink resolution and installed-metadata processing, skip that validation. A malicious package can ship an in-package binary symlink that resolves outside its installation directory. Alternatively, attacker-influenced vendor/composer/installed.json metadata can supply an escaping binary path during a reinstall or when Composer regenerates missing vendor/bin entries.
Root Cause
Composer enforces parent-directory validation inconsistently across its install pipeline. The symlink resolution routine and the installed.json metadata reader trust their inputs and pass paths directly to the binary installer. Composer then invokes chmod on the resolved target to make it world-readable and executable, and writes a proxy script under vendor/bin that references the external file.
Attack Vector
Exploitation requires local file operations and user interaction, typically running composer install or a reinstall. The installed-metadata path is reachable only when the vendor directory was not populated by the same validated install run. Common scenarios include vendors restored from an untrusted cache, copied from an earlier build stage, carried over from an older Composer run, or writable by a lower-trust build step. The issue does not by itself provide remote code execution or data exfiltration, but it enables trust escalation between build stages.
// Patch context from src/Composer/Downloader/FileDownloader.php
use Composer\Plugin\PostFileDownloadEvent;
use Composer\Plugin\PreFileDownloadEvent;
use Composer\EventDispatcher\EventDispatcher;
+use Composer\Installer\BinaryInstaller;
use Composer\Util\Filesystem;
use Composer\Util\Http\Response;
use Composer\Util\Platform;
Source: Composer commit 53b8bb4c and Composer commit ad649fdf. The fix routes binary path handling through BinaryInstaller, which enforces the parent-directory validation uniformly across symlink and metadata code paths.
Detection Methods for CVE-2026-59944
Indicators of Compromise
- Symlinks inside a package's bin directory whose targets resolve outside the package installation root.
- Entries in vendor/composer/installed.json referencing binary paths containing .. segments or absolute paths outside vendor/.
- Files outside vendor/ that unexpectedly have world-readable and executable permission bits set after a composer install run.
- Proxy scripts under vendor/bin/ referencing targets outside the project directory.
Detection Strategies
- Audit CI and build logs for composer install or composer update operations that ran against a pre-populated or cached vendor/ directory.
- Compare the resolved targets of every vendor/bin/* entry against the declared package installation paths.
- Scan installed dependencies for symlinks whose target paths escape their owning package directory.
- Validate installed.json binary entries against the corresponding composer.json declarations for each package.
Monitoring Recommendations
- Track file permission changes on paths outside the project root during dependency install operations.
- Alert on Composer runs executed by lower-trust build stages that write into vendor/.
- Log and review the Composer version pinned in CI images and developer workstations.
How to Mitigate CVE-2026-59944
Immediate Actions Required
- Upgrade Composer to version 2.2.30 for the 2.2.x branch or 2.10.3 for the 2.x branch.
- Rebuild all container images and CI runners that ship Composer to include the patched version.
- Discard any vendor/ directories that were populated by an unpatched Composer against untrusted dependencies.
- Reinstall dependencies with the patched Composer against a freshly cleaned vendor/ directory.
Patch Information
The fix is delivered in Composer releases 2.2.30 and 2.10.3. Full technical details are published in GitHub Security Advisory GHSA-96h3-5x6v-m776. The patches route binary path resolution through BinaryInstaller so parent-directory validation applies uniformly across the symlink and installed-metadata paths.
Workarounds
- Never reuse a vendor/ directory across build stages with different trust levels; always run composer install on an empty directory.
- Restrict write access to vendor/composer/installed.json to the same build stage that performs the validated install.
- Avoid restoring vendor/ from untrusted caches; scope cache keys to the trusted build environment only.
- Review third-party packages for symlinks in their bin entries before installation.
# Upgrade Composer to a patched release
composer self-update 2.10.3
# Or for the 2.2.x LTS branch
composer self-update 2.2.30
# Reinstall dependencies against a clean vendor directory
rm -rf vendor/ composer.lock
composer install --no-cache
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

