CVE-2026-48784: Symfony UrlGenerator Dot-Segment Encoding Skips Every Vulnerability
MODERATECVE-2026-48784 is a MODERATE urlgenerator dot-segment encoding skips every vulnerability (CWE-172: Encoding Error) affecting Symfony libraries in the Packagist ecosystem. The issue involves urlgenerator dot-segment encoding skips every other chained `../` or `./` → generated url collapses off-route under rfc 3986 normalization. Remediation is available by upgrading affected packages to version 5.4.53, 6.4.41, 7.4.13, 8.0.13.
CVE-2026-48784 at a Glance
How to Fix CVE-2026-48784
To remediate this vulnerability, upgrade all affected Symfony dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade symfony/routing to 5.4.53
Upgrade symfony/routing to 6.4.41
Upgrade symfony/routing to 7.4.13
Upgrade symfony/routing to 8.0.13
Upgrade symfony/symfony to 5.4.53
Upgrade symfony/symfony to 6.4.41
Upgrade symfony/symfony to 7.4.13
Upgrade symfony/symfony to 8.0.13
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for symfony/routing
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-48784, inspect your project dependencies for Symfony:
inspect dependencies for symfony/routing
Analyze the terminal output to locate any version of Symfony in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 5.4.53), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-172: Encoding Error, where the product does not properly encode or decode the data, resulting in unexpected values. In Symfony, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-48784 Affected Symfony Versions
8 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
symfony/routing
|
Packagist |
< 5.4.53
|
5.4.53
|
|
symfony/routing
|
Packagist |
≥ 6.0.0
< 6.4.41
|
6.4.41
|
|
symfony/routing
|
Packagist |
≥ 7.0.0
< 7.4.13
|
7.4.13
|
|
symfony/routing
|
Packagist |
≥ 8.0.0
< 8.0.13
|
8.0.13
|
|
symfony/symfony
|
Packagist |
< 5.4.53
|
5.4.53
|
|
symfony/symfony
|
Packagist |
≥ 6.0.0
< 6.4.41
|
6.4.41
|
|
symfony/symfony
|
Packagist |
≥ 7.0.0
< 7.4.13
|
7.4.13
|
|
symfony/symfony
|
Packagist |
≥ 8.0.0
< 8.0.13
|
8.0.13
|
References
Frequently Asked Questions
What is CVE-2026-48784?
Which Symfony versions are affected?
What version fixes CVE-2026-48784?
Is symfony/routing affected?
Is symfony/symfony affected?
What CWE is associated with CVE-2026-48784?
How can I check Packagist dependencies for CVE-2026-48784?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-h5x3-xfc9-m39h",
"modified" : "2026-06-15T17:33:46Z",
"published" : "2026-06-15T17:33:46Z",
"aliases" : [ "CVE-2026-48784" ],
"summary" : "Symfony: UrlGenerator Dot-Segment Encoding Skips Every Other Chained `../` or `./` → Generated URL Collapses Off-Route Under RFC 3986 Normalization",
"details" : "### Description\n\n`Symfony\\Component\\Routing\\Generator\\UrlGenerator::doGenerate()` percent-encodes `.` and `..` path segments so that the generated URL still resolves to the originating route after RFC 3986 §5.2.4 dot-segment removal (which strict RFC-3986 consumers — routers, reverse proxies, HTTP clients — perform *before* percent-decoding).\n\nThe encoding was implemented as `strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/'])` plus a trailing-segment fixup. `strtr` advances past the trailing `/` of each match, so the next dot-segment in a chained sequence was left unescaped:\n\n| Input | Output (before fix) | Expected |\n| -------------------- | ---------------------------------------- | ----------------------------------- |\n| `/../../../` | `/%2E%2E/../%2E%2E/` | `/%2E%2E/%2E%2E/%2E%2E/` |\n| `/foo/../../../bar` | `/foo/%2E%2E/../%2E%2E/bar` | `/foo/%2E%2E/%2E%2E/%2E%2E/bar` |\n\nWhen a route exposes a parameter constrained by a permissive requirement (`.+`, `.*`, or similar) that accepts dots and slashes, attacker-controlled chained `..` or `.` segments produce a generated URL that, under strict RFC 3986 normalization, collapses to a different path than the originating route. The Twig `path()` / `url()` helpers and any server-side use of `UrlGenerator` are affected. Same class of route round-trip integrity issue as CVE-2026-45065.\n\nNote: WHATWG-conformant browsers treat `%2E`/`%2E%2E` as dot-segments during URL parsing, so the encoding never protected browser-side traversal. The defense exists for RFC-3986-conformant consumers; restoring it for chained segments closes the gap there.\n\n### Resolution\n\n`UrlGenerator` now matches every `/.` or `/..` dot-segment in a single left-to-right `preg_replace_callback` pass using a lookahead that does not consume the trailing `/`, so adjacent dot-segments are encoded correctly.\n\nThe patches for this issue are available [here](https://github.com/symfony/symfony/commit/4b63c3a3f7af04ecd79c89a594b0b02a01990b1d) for branch 5.4 (and forward-ported to 6.4, 7.4, 8.0 and 8.1).\n\n### Credits\n\nSymfony would like to thank Alex Pott for reporting the issue and Nicolas Grekas for providing the fix.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/routing"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "5.4.53"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/routing"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "6.0.0"
}, {
"fixed" : "6.4.41"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/routing"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "7.0.0"
}, {
"fixed" : "7.4.13"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/routing"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "8.0.0"
}, {
"fixed" : "8.0.13"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/symfony"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "5.4.53"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/symfony"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "6.0.0"
}, {
"fixed" : "6.4.41"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/symfony"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "7.0.0"
}, {
"fixed" : "7.4.13"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "symfony/symfony"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "8.0.0"
}, {
"fixed" : "8.0.13"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/symfony/symfony/security/advisories/GHSA-h5x3-xfc9-m39h"
}, {
"type" : "WEB",
"url" : "https://github.com/symfony/symfony/commit/4b63c3a3f7af04ecd79c89a594b0b02a01990b1d"
}, {
"type" : "WEB",
"url" : "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/routing/CVE-2026-48784.yaml"
}, {
"type" : "WEB",
"url" : "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/symfony/CVE-2026-48784.yaml"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/symfony/symfony"
}, {
"type" : "WEB",
"url" : "https://symfony.com/cve-2026-48784"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-172", "CWE-601" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-06-15T17:33:46Z",
"nvd_published_at" : null
}
}