CVE-2026-45066 Overview
CVE-2026-45066 affects the Symfony PHP framework's HtmlSanitizer component. The vulnerability allows URLs outside the configured allowlist to pass through allowLinkHosts() or allowMediaHosts() policies. Two root causes drive the flaw. First, UrlSanitizer::parse() follows RFC 3986 while browsers implement WHATWG URL parsing, creating parsing divergence attackers can abuse. Second, <area href> attributes were validated against the media policy instead of the link policy. The issue impacts Symfony versions from 6.1.0-BETA1 through 6.4.39, 7.4.11, and 8.0.11. Fixes are available in 6.4.40, 7.4.12, and 8.0.12. The vulnerability is classified under [CWE-184] (Incomplete List of Disallowed Inputs).
Critical Impact
Attackers can bypass URL host allowlists in sanitized HTML, redirecting users to attacker-controlled domains via crafted anchor or area elements.
Affected Products
- Symfony 6.1.0-BETA1 through 6.4.39
- Symfony 7.0.0 through 7.4.11
- Symfony 8.0.0 through 8.0.11
Discovery Timeline
- 2026-07-14 - CVE-2026-45066 published to NVD
- 2026-07-16 - Last updated in NVD database
Technical Details for CVE-2026-45066
Vulnerability Analysis
The Symfony HtmlSanitizer component sanitizes untrusted HTML input and enforces host allowlists on link and media URLs. Applications use allowLinkHosts() to restrict where <a href> values may point, and allowMediaHosts() to restrict <img>, <video>, and similar media sources. The URL sanitizer parses candidate URLs with UrlSanitizer::parse() and compares the resulting host to the configured allowlist. When the parsed host does not match, sanitization returns null and the URL is stripped. The vulnerability breaks this guarantee in two ways, allowing attacker-controlled hosts to survive sanitization and reach the browser.
Root Cause
The first root cause is a parser mismatch. UrlSanitizer::parse() follows RFC 3986 semantics, while modern browsers implement the WHATWG URL specification. The two specifications diverge in handling backslashes, extra slashes after the scheme, and other edge cases. An attacker can craft a URL that RFC 3986 parses with a benign host but browsers resolve to an attacker-controlled origin. The second root cause is an element mapping error in UrlAttributeSanitizer. The <area> element, which supports an href attribute like <a>, was routed through the media allowlist rather than the link allowlist. Applications relying on allowLinkHosts() to constrain navigation targets did not enforce that policy on <area> elements.
Attack Vector
An attacker submits crafted HTML containing an anchor or area element whose href exploits the parser divergence. Once sanitized HTML is rendered, browsers follow the WHATWG-resolved target to an off-allowlist host. User interaction, such as clicking the link, is required to trigger navigation.
// Patch: src/Symfony/Component/HtmlSanitizer/TextSanitizer/UrlSanitizer.php
return null;
}
+ if (false !== strpbrk($input, '\\') || preg_match('~^(?:https?|ftp|wss?):(/[^/]|///)~i', $input)) {
+ return null;
+ }
+
$url = self::parse($input);
// Malformed URL
// Patch: src/Symfony/Component/HtmlSanitizer/Visitor/AttributeSanitizer/UrlAttributeSanitizer.php
public function sanitizeAttribute(string $element, string $attribute, string $value, HtmlSanitizerConfig $config): ?string
{
- if ('a' === $element) {
+ if (\in_array($element, ['a', 'area'], true)) {
return UrlSanitizer::sanitize(
$value,
$config->getAllowedLinkSchemes(),
// Source: https://github.com/symfony/symfony/commit/d506b556d3d3906f3e8660ad82257ce87edbaac4
The patch rejects inputs containing backslashes or scheme prefixes followed by irregular slash counts before parsing. It also adds area to the list of elements evaluated against the link scheme and host allowlist.
Detection Methods for CVE-2026-45066
Indicators of Compromise
- HTML content stored or rendered by the application containing <a> or <area> elements with href values using backslashes or unusual slash sequences after the scheme, such as http:\\evil.example or https:///evil.example.
- Outbound navigation from application pages to hosts absent from the configured allowLinkHosts() or allowMediaHosts() policies.
- Requests to the application submitting user-generated HTML containing <area shape="default" href="..."> targeting external domains.
Detection Strategies
- Audit Composer lock files for symfony/html-sanitizer versions prior to 6.4.40, 7.4.12, or 8.0.12.
- Review stored HTML content for anchor and area elements whose parsed host differs between RFC 3986 and WHATWG interpretations.
- Compare sanitizer output against browser-resolved navigation targets in integration tests using both parsing models.
Monitoring Recommendations
- Log referrer headers on outbound clicks and alert when destinations fall outside the application's configured link allowlist.
- Monitor web application firewall logs for requests containing HTML payloads with href attributes that mix backslashes with URL schemes.
- Track user reports of unexpected redirects originating from user-generated content areas.
How to Mitigate CVE-2026-45066
Immediate Actions Required
- Upgrade symfony/html-sanitizer to 6.4.40, 7.4.12, or 8.0.12 depending on the major branch in use.
- Re-sanitize stored HTML content that was processed by vulnerable versions if that content is displayed to other users.
- Review application code paths that rely on allowLinkHosts() or allowMediaHosts() as a security boundary.
Patch Information
The fix is delivered in commit d506b556d3d3906f3e8660ad82257ce87edbaac4, released in Symfony v6.4.40, Symfony v7.4.12, and Symfony v8.0.12. Details are published in GitHub Security Advisory GHSA-qc95-4862-92fh.
Workarounds
- Add application-level validation that re-parses sanitized URLs using a WHATWG-compliant parser before rendering.
- Strip <area> elements entirely from user-supplied HTML until upgrading is possible.
- Restrict allowed link schemes to https only via allowLinkSchemes(['https']) to reduce the surface exposed by parser divergence.
# Upgrade via Composer
composer require symfony/html-sanitizer:^6.4.40
# or
composer require symfony/html-sanitizer:^7.4.12
# or
composer require symfony/html-sanitizer:^8.0.12
# Verify installed version
composer show symfony/html-sanitizer | grep versions
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

