Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-48784

CVE-2026-48784: Symfony Path Traversal Vulnerability

CVE-2026-48784 is a path traversal flaw in Sensiolabs Symfony that allows attackers to manipulate route parameters and generate malicious URLs. This post covers technical details, affected versions, and patches.

Published:

CVE-2026-48784 Overview

CVE-2026-48784 is a URL generation flaw in the Symfony PHP framework's Routing component. The UrlGenerator::doGenerate() method used strtr() to encode dot-segments, a sequential replacement strategy that skipped every other chained ../ or ./ segment. Attacker-controlled route parameters can therefore produce URLs that collapse to a different path once RFC 3986 normalization is applied by a client. The issue affects Symfony releases prior to 5.4.53, 6.4.41, 7.4.13, and 8.0.13. The weakness is classified as [CWE-172] Encoding Error.

Critical Impact

Attackers who control route parameter values can craft URLs that resolve to unintended paths after browser normalization, enabling open redirect-style abuse and routing-integrity issues.

Affected Products

  • Symfony 5.x prior to 5.4.53
  • Symfony 6.x prior to 6.4.41
  • Symfony 7.x prior to 7.4.13
  • Symfony 8.x prior to 8.0.13

Discovery Timeline

  • 2026-07-14 - CVE-2026-48784 published to NVD
  • 2026-07-15 - Last updated in NVD database

Technical Details for CVE-2026-48784

Vulnerability Analysis

Symfony's Routing component generates URLs from route definitions and user-supplied parameter values. To prevent . and .. segments from being interpreted as relative references per RFC 3986 Section 3.3, the generator must percent-encode them. The vulnerable implementation performed this encoding with a single strtr() call using the map ['/../' => '/%2E%2E/', '/./' => '/%2E/'].

Because strtr() scans the string once and does not reprocess characters it has already substituted, chained sequences such as /././. or /../../.. leave alternating segments untouched. A subsequent RFC 3986 normalization performed by the user agent then interprets the surviving dot-segments and collapses the URL to a different resource path than the developer intended.

Root Cause

The root cause is an incorrect encoding algorithm. strtr() performs non-overlapping replacements from left to right, so when two candidate matches share a boundary character (the /), only every second occurrence is replaced. The trailing-segment handling with str_ends_with($url, '/..') and str_ends_with($url, '/.') also failed to cover the intermediate skipped segments.

Attack Vector

Exploitation requires a Symfony application that inserts untrusted input into a route parameter and returns the generated URL to a browser (for example in a redirect, an href, or a Location header). The attacker supplies a parameter value containing chained ../ or ./ sequences. When the victim's browser normalizes the resulting URL, it resolves to a path chosen by the attacker rather than the developer-intended route.

php
         // the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
         // so we need to encode them as they are not used for this purpose here
         // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
-        $url = strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/']);
-        if (str_ends_with($url, '/..')) {
-            $url = substr($url, 0, -2).'%2E%2E';
-        } elseif (str_ends_with($url, '/.')) {
-            $url = substr($url, 0, -1).'%2E';
+        if (str_contains($url, '/.')) {
+            $segments = explode('/', $url);
+            foreach ($segments as $i => $segment) {
+                if ('.' === $segment) {
+                    $segments[$i] = '%2E';
+                } elseif ('..' === $segment) {
+                    $segments[$i] = '%2E%2E';
+                }
+            }
+            $url = implode('/', $segments);
+        }

Source: Symfony patch commit 4b63c3a. The fix replaces the sequential strtr() approach with a segment-by-segment walk that encodes every . and .. regardless of position.

Detection Methods for CVE-2026-48784

Indicators of Compromise

  • Generated URLs in application logs containing raw .. or . path segments produced by UrlGenerator.
  • HTTP Location response headers whose target path collapses to an unexpected route after normalization.
  • Route parameter values in request logs containing repeated ../ or ./ sequences.

Detection Strategies

  • Inventory PHP dependencies with composer show symfony/routing or composer show symfony/symfony and flag versions below 5.4.53, 6.4.41, 7.4.13, or 8.0.13.
  • Add unit tests that feed chained dot-segment input into any route parameter and assert the generated URL contains only %2E sequences.
  • Enable web application firewall rules that inspect request parameters for ../ and ./ chains when those parameters feed URL generation.

Monitoring Recommendations

  • Monitor outbound redirects for host and path mismatches between the intended route and the emitted URL.
  • Alert on 3xx responses where the Location value differs structurally from any registered route pattern.
  • Track route parameter values written to session, cache, or database that may later be rendered as links.

How to Mitigate CVE-2026-48784

Immediate Actions Required

  • Upgrade Symfony to 5.4.53, 6.4.41, 7.4.13, or 8.0.13 depending on the branch in use.
  • Audit controllers and templates for uses of UrlGeneratorInterface::generate() that receive untrusted parameter values.
  • Validate route parameters against strict allow-lists before passing them to the generator.

Patch Information

The fix is delivered in Symfony releases v5.4.53, v6.4.41, and v7.4.13. The patch is documented in GitHub Security Advisory GHSA-h5x3-xfc9-m39h and implemented in commit 4b63c3a. Update via Composer to receive the corrected UrlGenerator::doGenerate() implementation.

Workarounds

  • Reject any route parameter value containing ., .., /, or backslash characters before invoking the URL generator.
  • Wrap generated URLs with an application-side normalizer that re-encodes remaining dot-segments before emission.
  • Restrict redirects to a fixed allow-list of destinations rather than trusting generator output for Location headers.
bash
# Upgrade the vulnerable Routing component to a patched release
composer require symfony/routing:^7.4.13
# Or update the full framework metapackage
composer update symfony/symfony
# Verify the installed version
composer show symfony/routing | grep versions

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.