{"id":"CVE-2026-55878","title":"symfony/ux-toolkit: Path Traversal Allows Arbitrary File Write and Read via Crafted Recipe Manifest","summary":"symfony/ux-toolkit: Path Traversal Allows Arbitrary File Write and Read via Crafted Recipe Manifest","severity":"high","cvss":7.8,"cwe":["CWE-22"],"vendor":"symfony","product":"symfony/ux-toolkit","ecosystem":"composer","affected":["symfony/ux-toolkit >= 2.32.0, < 2.36.1","symfony/ux-toolkit >= 3.0.0, < 3.2.0"],"patched":["symfony/ux-toolkit 2.36.1","symfony/ux-toolkit 3.2.0"],"published":"2026-06-19","updated":"2026-06-19","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-p9xj-fpr2-jf2q","references":[{"url":"https://github.com/symfony/ux/security/advisories/GHSA-p9xj-fpr2-jf2q"},{"url":"https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/ux-toolkit/CVE-2026-55878.yaml"},{"url":"https://github.com/advisories/GHSA-p9xj-fpr2-jf2q"}],"tags":["ghsa","composer"],"ingestedAt":"2026-06-22T13:35:24.274Z","epss":0.00192,"epssPercentile":0.09151,"slug":"CVE-2026-55878","body":"## Overview\n\n### Description\nThe `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.\n\nBecause 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.\n\n### Resolution\n\nThe 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.\n\n### Credits\n\nSymfony would like to thank Pascal Cescon for reporting the issue and Hugo Alliaume for providing the fix.\n\n## Affected packages\n\n- `symfony/ux-toolkit >= 2.32.0, < 2.36.1`\n- `symfony/ux-toolkit >= 3.0.0, < 3.2.0`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `symfony/ux-toolkit 2.36.1`\n- `symfony/ux-toolkit 3.2.0`","depth":"twilight","depthScore":43,"depthScoreParts":{"impact":42.9,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}