CVE-2026-55878 Overview
CVE-2026-55878 is a path traversal vulnerability [CWE-22] in Symfony UX, a JavaScript ecosystem for Symfony applications. The flaw resides in the ux:install console command, which installs files from a recipe kit by copying paths listed in a copy-files map. Because Path::isRelative() accepts relative paths containing .. segments such as ../../../etc, a crafted or compromised recipe kit can write attacker-controlled content to arbitrary locations or read local files outside the recipe directory. The vulnerability affects Symfony UX from 2.32.0 before 2.36.1 and from 3.0.0 before 3.2.0. Fixed versions are 2.36.1 and 3.2.0.
Critical Impact
A malicious or compromised recipe kit can achieve arbitrary file write and local file disclosure on the developer or build host running ux:install, enabling code execution through overwritten configuration or application files.
Affected Products
- Symfony UX Toolkit 2.32.0 through versions before 2.36.1
- Symfony UX Toolkit 3.0.0 through versions before 3.2.0
- Any Symfony application invoking the ux:install console command with untrusted recipe kits
Discovery Timeline
- 2026-07-08 - CVE-2026-55878 published to NVD
- 2026-07-08 - Last updated in NVD database
Technical Details for CVE-2026-55878
Vulnerability Analysis
The ux:install command copies files described in a recipe kit's copy-files map from a source path inside the kit to a destination path inside the target project. Input validation is limited to Path::isRelative(), which only enforces that the string is not absolute. It does not reject relative paths that traverse upward using .. segments. An entry such as ../../../etc/passwd as a source path allows the installer to read outside the recipe directory, and a destination like ../../../var/www/html/config/services.php allows overwriting files outside the project root. Because the command runs with the privileges of the developer or CI user executing it, the impact extends to any file writable by that account, including configuration, cron files, or SSH authorized keys.
Root Cause
The root cause is missing directory containment validation in the recipe installer. Path::isRelative() returns true for paths beginning with .., so no check ensured that source and destination paths remained within their expected base directories. The fix introduces Assert::pathDoesNotEscapeDirectory(), which splits the path on / and \ separators and rejects any .. segment.
Attack Vector
Exploitation requires a user to run ux:install against a crafted or compromised recipe kit. This may occur through supply-chain compromise of a legitimate kit, a typosquatted kit name, or social engineering directing a developer to install an attacker-controlled kit. User interaction is required, and the attack executes in the local context of the developer or automation runner.
// Security patch in src/Toolkit/src/Assert.php
// Rejects any path containing a ".." segment using / or \ separators.
/**
* Assert that a relative path does not escape its target directory through a ".." segment.
*
* @throws \InvalidArgumentException if the path escapes its target directory
*/
public static function pathDoesNotEscapeDirectory(string $path): void
{
if (\in_array('..', preg_split('#[\\\\/]+#', $path), true)) {
throw new \InvalidArgumentException(\sprintf('The path "%s" must not escape its target directory.', $path));
}
}
Source: Symfony UX commit 7b4ddf3
// Security patch in src/Toolkit/src/File.php
// Both source and destination paths are now validated against directory escape.
if (!Path::isRelative($this->destinationRelativePathName)) {
throw new \InvalidArgumentException(\sprintf('The destination path "%s" must be relative.', $this->destinationRelativePathName));
}
Assert::pathDoesNotEscapeDirectory($this->sourceRelativePathName);
Assert::pathDoesNotEscapeDirectory($this->destinationRelativePathName);
Source: Symfony UX commit 7b4ddf3
Detection Methods for CVE-2026-55878
Indicators of Compromise
- Recipe kit manifests containing copy-files map entries with .. segments in source or destination paths.
- Unexpected file writes outside the project root shortly after invocation of the ux:install command.
- Reads of sensitive local files such as /etc/passwd, SSH keys, or environment files by the PHP process running the Symfony console.
- Presence of Symfony UX Toolkit versions in the vulnerable range (2.32.0–2.36.0 or 3.0.0–3.1.x) in composer.lock.
Detection Strategies
- Scan repositories and container images for vulnerable Symfony UX Toolkit versions using software composition analysis.
- Inspect any custom or third-party recipe kits for .. sequences in copy-files map source or destination fields.
- Audit CI/CD logs for invocations of bin/console ux:install and correlate with subsequent filesystem changes outside the workspace.
Monitoring Recommendations
- Monitor developer workstations and build agents for PHP processes writing to paths outside the project directory tree.
- Alert on modifications to sensitive files such as authorized_keys, cron directories, and web server configuration during package installation events.
- Track composer require and composer update events involving symfony/ux-* packages and correlate against approved kit sources.
How to Mitigate CVE-2026-55878
Immediate Actions Required
- Upgrade Symfony UX Toolkit to 2.36.1 or 3.2.0 in all projects and CI pipelines.
- Avoid running ux:install against recipe kits from untrusted or unverified sources until upgrades are complete.
- Review recent ux:install executions on developer machines and build hosts for signs of file writes outside project directories.
Patch Information
The vulnerability is fixed in Symfony UX Toolkit 2.36.1 and 3.2.0. The patch adds Assert::pathDoesNotEscapeDirectory() and applies it to both sourceRelativePathName and destinationRelativePathName in the recipe file installer. See the GitHub Security Advisory GHSA-p9xj-fpr2-jf2q, the v2.36.1 release notes, and the v3.2.0 release notes.
Workarounds
- Only install recipe kits from verified, first-party sources until the upgrade is deployed.
- Manually inspect the copy-files map of any recipe kit for .. segments before running ux:install.
- Run ux:install inside an ephemeral, unprivileged container with no access to sensitive host directories.
# Upgrade Symfony UX Toolkit to a fixed release
composer require symfony/ux-toolkit:^2.36.1
# or, for the 3.x branch
composer require symfony/ux-toolkit:^3.2.0
# Verify the installed version
composer show symfony/ux-toolkit | grep versions
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

