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+202A–U+202E and U+2066–U+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.
// 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+202A–U+202E and U+2066–U+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.
# 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.

