---
id: "GHSA-6prc-h956-hxjq"
page: "https://infrastack.ai/live/GHSA-6prc-h956-hxjq"
kind: "vulnerability"
aliases: ["GHSA-6prc-h956-hxjq"]
title: "Filesystem Path Treats Any Prefix Before \"://\" as a Root, Letting Paths Escape Their Base Directory"
severity: "high"
cvss: null
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "symfony/filesystem", "note": ">=5.4.0, <5.4.56", "fixed": ["5.4.56"], "affected": ">= 5.4.0, < 5.4.56", "ecosystem": "composer"}, {"name": "symfony/filesystem", "note": ">=6, <6.4.50", "fixed": ["6.4.50"], "affected": ">= 6, < 6.4.50", "ecosystem": "composer"}, {"name": "symfony/filesystem", "note": ">=7, <7.4.23", "fixed": ["7.4.23"], "affected": ">= 7, < 7.4.23", "ecosystem": "composer"}, {"name": "symfony/filesystem", "note": ">=8, <8.1.11", "fixed": ["8.1.11"], "affected": ">= 8, < 8.1.11", "ecosystem": "composer"}, {"name": "symfony/symfony", "note": ">=5.4.0, <5.4.56", "fixed": ["5.4.56"], "affected": ">= 5.4.0, < 5.4.56", "ecosystem": "composer"}, {"name": "symfony/symfony", "note": ">=6, <6.4.50", "fixed": ["6.4.50"], "affected": ">= 6, < 6.4.50", "ecosystem": "composer"}, {"name": "symfony/symfony", "note": ">=7, <7.4.23", "fixed": ["7.4.23"], "affected": ">= 7, < 7.4.23", "ecosystem": "composer"}, {"name": "symfony/symfony", "note": ">=8, <8.1.11", "fixed": ["8.1.11"], "affected": ">= 8, < 8.1.11", "ecosystem": "composer"}]
ecosystems: ["composer"]
tags: ["assetmapper", "composer", "cwe-22", "package", "php", "symfony", "symfony-filesystem"]
not_affected_if: ["auth-required", "no-user-input-in-paths", "static-paths-only"]
published_at: "2026-11-04T11:43:35+00:00"
first_seen_at: "2026-11-09T22:53:32+00:00"
updated_at: "2026-11-09T22:58:42+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/symfony/symfony/security/advisories/GHSA-6prc-h956-hxjq", "first_seen_at": "2026-11-09T22:53:32+00:00"}]
exploit_sources: []
---

# Filesystem Path Treats Any Prefix Before "://" as a Root, Letting Paths Escape Their Base Directory

Link for people: https://infrastack.ai/live/GHSA-6prc-h956-hxjq (this .md is for agents)

The Symfony Filesystem Path helpers treat anything before the first "://" as a root, so ".." segments in that prefix are not resolved. An application that checks or opens user-built paths with isBasePath(), canonicalize() or similar can be made to read or write files outside its intended directory; AssetMapper can also be made to write files outside assets/vendor via a malicious remote package's CSS.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- composer:symfony/filesystem affected >= 5.4.0, < 5.4.56 fixed 5.4.56
- composer:symfony/filesystem affected >= 6, < 6.4.50 fixed 6.4.50
- composer:symfony/filesystem affected >= 7, < 7.4.23 fixed 7.4.23
- composer:symfony/filesystem affected >= 8, < 8.1.11 fixed 8.1.11
- composer:symfony/symfony affected >= 5.4.0, < 5.4.56 fixed 5.4.56
- composer:symfony/symfony affected >= 6, < 6.4.50 fixed 6.4.50
- composer:symfony/symfony affected >= 7, < 7.4.23 fixed 7.4.23
- composer:symfony/symfony affected >= 8, < 8.1.11 fixed 8.1.11

## How to check

- Check the installed version with `composer show symfony/filesystem` and `composer show symfony/symfony`, and compare against the fixed versions below.
- Search application code for calls to `Path::isBasePath`, `Path::canonicalize`, `Path::join` or `Path::makeAbsolute` applied to user-supplied paths before a file is opened.
- On Symfony 6.4 or later, check whether the AssetMapper component is used with `importmap:require` or `importmap:install`.

## Fix

- `symfony/filesystem` 5.4 branch: `5.4.56`; 6.x: `6.4.50`; 7.x: `7.4.23`; 8.x: `8.1.11`
- `symfony/symfony` 5.4 branch: `5.4.56`; 6.x: `6.4.50`; 7.x: `7.4.23`; 8.x: `8.1.11`

## Timeline

- 2026-11-09T22:53:32+00:00 ghsa-repo https://github.com/symfony/symfony/security/advisories/GHSA-6prc-h956-hxjq

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/symfony/symfony/security/advisories/GHSA-6prc-h956-hxjq

## From the sources

### Description

Most methods of `Symfony\Component\Filesystem\Path` rely on `Path::split()`, which takes everything before the first `://` as the root of a path. It doesn't check that this prefix is a URI scheme, so the `..` segments in that prefix are never resolved. PHP sees a scheme only at the start of a string. So `/base/../x://../secret.txt` is a plain local path to `/secret.txt` for PHP, while `Path::isBasePath('/base', '/base/../x://../secret.txt')` returns `true`. `canonicalize()`, `join()`, `makeAbsolute()` and `makeRelative()` are affected the same way.

Some applications check a path built from user input with `isBasePath()` or `canonicalize()`, and then open it. They can be made to read or write files outside the expected directory.

On Symfony 6.4 and later, the AssetMapper component builds with `Path::join()` the path of the files that a remote package references from its CSS. A malicious or compromised package can therefore make `importmap:require` or `importmap:install` write a file of its choice outside `assets/vendor`. For example, the CSS `url(../../../../../public/x://shell.php)` writes `public/x:/shell.php`.

### Resolution

A prefix is now a scheme only when PHP would look for a stream wrapper with that name. That is two or more letters, digits, `+`, `-` or `.`, followed by `://` at the start of the path. Other prefixes are regular path segments, and the `..` segments after them are resolved. Real schemes such as `phar://`, `file://`, `vfs://` or `compress.zlib://` keep working.

The patch for this issue is available [here](https://github.com/symfony/symfony/commit/9441dd5f05e78ad898317083828c1acebff586a1) for branch 5.4 (and forward-ported to 6.4, 7.4, 8.1 and 8.2).

### Credits

We would like to thank Nicolas Grekas for reporting the issue and providing the fix.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
