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

CVE-2026-45064: Sensiolabs Symfony XSS Vulnerability

CVE-2026-45064 is an XSS flaw in Sensiolabs Symfony that enables phishing attacks through visual spoofing of link destinations. This post covers technical details, affected versions, impact, and mitigation steps.

Updated:

CVE-2026-45064 Overview

CVE-2026-45064 affects the Symfony PHP framework's HtmlSanitizer component. The UrlSanitizer::parse() method passes Unicode explicit-direction bidirectional (BiDi) formatting characters into sanitized href and src attributes. Attackers can craft URLs where the visually rendered destination differs from the actual navigation target, enabling phishing-style visual spoofing [CWE-451]. The flaw exists from version 6.1.0-BETA1 until 6.4.40, 7.4.12, and 8.0.12. Symfony maintainers resolved the issue in versions 6.4.40, 7.4.12, and 8.0.12.

Critical Impact

Sanitized links may render deceptive URLs to end users, facilitating phishing attacks against applications that rely on Symfony's HtmlSanitizer for user-generated content.

Affected Products

  • Symfony 6.1.0-BETA1 through 6.4.39
  • Symfony 7.x prior to 7.4.12
  • Symfony 8.x prior to 8.0.12

Discovery Timeline

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

Technical Details for CVE-2026-45064

Vulnerability Analysis

The vulnerability resides in src/Symfony/Component/HtmlSanitizer/TextSanitizer/UrlSanitizer.php. The UrlSanitizer::parse() function processes URLs supplied as href and src attribute values without filtering Unicode BiDi control characters. These characters, defined in the Unicode ranges U+202AU+202E and U+2066U+2069, alter the visual direction of text rendering in browsers.

When an attacker embeds these characters inside a URL, the sanitized output preserves them. Browsers then render the visible URL differently from the actual link target. A link appearing to point to a trusted domain can navigate the user to an attacker-controlled destination.

Root Cause

The underlying cause is missing input validation for Unicode BiDi formatting characters within the URL sanitization pipeline. The sanitizer trusted UriString::parse() output without stripping or rejecting characters that produce security-relevant visual ambiguity. This maps to CWE-451: User Interface (UI) Misrepresentation of Critical Information.

Attack Vector

Exploitation requires an attacker to submit HTML content containing crafted URLs to an application that uses Symfony's HtmlSanitizer. When a victim views the sanitized content, the displayed URL differs from the actual destination. Successful exploitation depends on user interaction such as clicking the malicious link.

php
// Patch excerpt from UrlSanitizer::parse()
try {
    // Reject explicit-direction BiDi formatting characters: they have no
    // legitimate place in a URL and enable visual spoofing of the rendered
    // href when the URL is later embedded in HTML.
    if (preg_match('/[\x{202A}-\x{202E}\x{2066}-\x{2069}]/u', $url)) {
        return null;
    }

    // Browsers tolerate spaces inside path/query/fragment by transparently
    // percent-encoding them. Mirror that behavior, but never inside the
    // scheme or authority (where spaces are illegal); the whitespace check
    // below rejects any space that didn't fit in the encoded slice.
    if (str_contains($url, ' ')) {
        if (str_starts_with($url, ' ')) {
            return null;
        }

        if (false !== $i = strpos($url, '://')) {
            $i += 3 + strcspn($url, '/?#', $i + 3);
        } elseif (str_starts_with($url, '//')) {
            $i = 2 + strcspn($url, '/?#', 2);
        } elseif (preg_match('#^[a-z][a-z0-9+.\-]*:#i', $url)) {
            // Hostless scheme (data:, mailto:, …): leave the URL untouched
            // and let the whitespace check reject it.
            $i = \strlen($url);
        } else {
            $i = 0;

Source: Symfony GitHub Commit 743a435. The patch rejects any URL containing BiDi override characters and percent-encodes spaces outside scheme and authority segments.

Detection Methods for CVE-2026-45064

Indicators of Compromise

  • Stored user-generated content containing Unicode code points U+202A through U+202E or U+2066 through U+2069 inside href or src attributes.
  • Anchor tags where the visible link text and the underlying href value resolve to different domains after BiDi processing.
  • Outbound HTTP referrers from application pages to unexpected domains following user clicks on sanitized content.

Detection Strategies

  • Scan database columns and content stores that hold HTML sanitized by Symfony for the BiDi character ranges listed above.
  • Enable application-layer logging on HtmlSanitizer invocations and record the pre- and post-sanitization URL strings for comparison.
  • Review dependency manifests (composer.lock) across all applications to enumerate installations of Symfony versions prior to the fixed releases.

Monitoring Recommendations

  • Monitor phishing report queues for user complaints referencing links that pointed to unexpected destinations.
  • Track anomalous redirects from application domains to newly registered or low-reputation external domains.
  • Alert on new content submissions containing Unicode general category Cf (format) characters within URL attributes.

How to Mitigate CVE-2026-45064

Immediate Actions Required

  • Upgrade Symfony to version 6.4.40, 7.4.12, or 8.0.12 depending on the branch in use.
  • Audit stored HTML content produced before the upgrade and strip BiDi control characters from existing href and src values.
  • Enumerate all applications that consume the symfony/html-sanitizer package and confirm patched versions are deployed.

Patch Information

The fix is contained in commit 743a435e948b897ef2b5564ac438d4beb95d2526 and shipped in the Symfony v6.4.40 release, Symfony v7.4.12 release, and Symfony v8.0.12 release. Full details are available in GitHub Security Advisory GHSA-h5vq-qfcg-4m6p.

Workarounds

  • Add a pre-processing filter that rejects or removes characters in the ranges U+202AU+202E and U+2066U+2069 before passing URLs to the sanitizer.
  • Implement a Content Security Policy (CSP) that restricts navigation targets to an allowlist of trusted domains.
  • Display fully decoded destination URLs alongside link text in user-facing views so recipients can verify the true target.
bash
# Configuration example: upgrade via Composer
composer require symfony/html-sanitizer:^6.4.40
# or, for the 7.x branch
composer require symfony/html-sanitizer:^7.4.12
# or, for the 8.x branch
composer require symfony/html-sanitizer:^8.0.12

# Verify installed version
composer show symfony/html-sanitizer

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.