Skip to main content

Symfony UX Toolkit CVE-2026-55878

HIGH
Path Traversal (CWE-22)
2026-06-19 https://github.com/symfony/ux GHSA-p9xj-fpr2-jf2q
7.8
CVSS 3.1 · Vendor: https://github.com/symfony/ux
Share

Severity by source

Vendor (https://github.com/symfony/ux) PRIMARY
7.8 HIGH
AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
vuln.today AI
7.8 HIGH

Local console command (AV:L), no auth needed by the kit author (PR:N), but the victim must invoke `ux:install` against the malicious kit (UI:R); arbitrary file read/write yields full C/I/A impact.

3.1 AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
4.0 AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/symfony/ux).

CVSS VectorVendor: https://github.com/symfony/ux

Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

2
Source Code Evidence Fetched
Jun 19, 2026 - 23:36 vuln.today
Analysis Generated
Jun 19, 2026 - 23:36 vuln.today

DescriptionCVE.org

Description

The ux:install console command installs files from a recipe kit by copying paths listed in a copy-files map. The only guard against malicious paths was Path::isRelative(), which returns true for paths like ../../../etc. Path::join() then resolves the .. segments without complaint, so the final path can escape the intended directory entirely. A crafted or compromised kit can therefore write attacker-controlled content to arbitrary locations on the developer's machine or CI runner.

Because the copy operation creates missing parent directories and can overwrite existing files silently (with --force or in non-interactive environments), an attacker who controls a kit can overwrite files such as controllers, git hooks, or .env to achieve code execution. The source side of copy-files is symmetrically affected, enabling local file reads outside the recipe directory.

Resolution

The fix introduces an Assert::pathDoesNotEscapeDirectory() helper that rejects any copy-files source or destination path containing a .. segment, regardless of whether / or \ is used as the separator. This check is enforced in both RecipeManifest (which also guards the source Finder) and File. As a last line of defense, the installer re-verifies the fully resolved paths with Path::isBasePath() immediately before each filesystem read and write.

Credits

Symfony would like to thank Pascal Cescon for reporting the issue and Hugo Alliaume for providing the fix.

AnalysisAI

Arbitrary file write and read in Symfony UX Toolkit's ux:install console command allows a crafted or compromised recipe kit to escape the intended installation directory and overwrite or read attacker-controlled files on a developer's machine or CI runner. Because overwriting controllers, git hooks, or .env files yields code execution, this path-traversal flaw escalates to local RCE, and no public exploit identified at time of analysis though the fix and root cause are documented in the upstream GHSA.

Technical ContextAI

The vulnerability lives in the recipe-kit installation logic of the symfony/ux-toolkit Composer package. The copy-files map in a recipe manifest lists source and destination paths, which were only validated with Path::isRelative() - a check that returns true for traversal strings such as ../../../etc. Path::join() then collapses the .. segments without rejecting them, so the resolved path can land anywhere on the filesystem the PHP process can reach. This is a textbook CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) and applies symmetrically: the source side enables out-of-tree reads, and the destination side enables out-of-tree writes, including silent overwrite when --force is supplied or the command runs non-interactively (e.g., CI).

RemediationAI

Vendor-released patch: upgrade symfony/ux-toolkit to 2.36.1 on the 2.x branch or to 3.2.0 on the 3.x branch via composer update symfony/ux-toolkit, as documented in GHSA-p9xj-fpr2-jf2q (https://github.com/symfony/ux/security/advisories/GHSA-p9xj-fpr2-jf2q). The fix introduces an Assert::pathDoesNotEscapeDirectory() helper that rejects .. segments using either separator and re-verifies fully resolved paths with Path::isBasePath() immediately before each read and write. Until the upgrade is applied, do not run ux:install against untrusted or unaudited recipe kits, avoid the --force flag, and review any copy-files manifests for .. segments before installing; in CI, pin kit sources to known-good revisions and run installs in ephemeral containers so that arbitrary writes cannot persist into source trees or credentials stores.

Share

CVE-2026-55878 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy