Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Primary rating from Vendor (https://github.com/symfony/symfony) · only source for this CVE.
CVSS VectorVendor: https://github.com/symfony/symfony
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Lifecycle Timeline
3DescriptionCVE.org
Description
symfony/html-sanitizer lets applications sanitise untrusted HTML. The configuration methods allowLinkHosts([...]) and allowLinkSchemes([...]) are intended to restrict <a href> targets to an allowlist of hosts/schemes; allowMediaHosts() / allowMediaSchemes() do the same for <img src> etc.
Three distinct bypasses allow a content author to smuggle off-allowlist URLs past these checks. First, UrlSanitizer::parse() parses the input following RFC-3986, while browsers follow the WHATWG URL Standard which normalises \ to / before parsing the authority of "special" schemes; so an input like https://evil\@trusted.com/ parses with host trusted.com server-side but navigates to https://evil/ in the browser. Second, WHATWG collapses any run of / after the scheme into //, while RFC-3986 does not; so https:/evil.com/ and https:///evil.com/ parse as host-less (skipping the host allowlist) but resolve to evil.com in the browser. Third, UrlAttributeSanitizer checks 'a' === $element to route to the link policy and falls through to the media policy otherwise, but <area> is a navigable hyperlink equivalent to <a>; so <area href> was sanitised against the media policy (which typically allows data: and may have no host allowlist), bypassing allowLinkHosts() / allowLinkSchemes() entirely.
Resolution
UrlSanitizer::sanitize() now rejects URLs that contain a backslash or that use a special scheme (http, https, ftp, ws, wss) followed by a single slash or three slashes before parsing, eliminating the parser-differential bypasses. UrlAttributeSanitizer now applies the link policy to both <a> and <area> elements.
The patch for this issue is available here for branch 5.4.
Credits
Symfony would like to thank Claude Mythos Preview (via Project Glasswing) for reporting the issue and providing the fix.
AnalysisAI
Three distinct URL allowlist bypasses in Symfony's symfony/html-sanitizer component allow content authors to smuggle off-allowlist URLs past host and scheme restriction controls configured via allowLinkHosts(), allowLinkSchemes(), allowMediaHosts(), and allowMediaSchemes(). The root cause is a combination of parser-differential attacks exploiting divergence between RFC-3986 (used server-side) and the WHATWG URL Standard (used by browsers), plus misclassification of <area> elements as media rather than navigable links. Affected applications processing untrusted HTML with host/scheme allowlists in symfony/html-sanitizer 6.1.0-6.4.39, 7.0.0-7.4.11, and 8.0.0-8.0.11 are at risk; no public exploit identified at time of analysis and this CVE does not appear in CISA KEV.
Technical ContextAI
The vulnerability class is CWE-184 (Incomplete List of Disallowed Inputs) - the sanitizer's URL validation logic fails to account for all syntactic forms that browsers will accept and resolve. Three mechanisms are exploited: (1) Backslash normalization: The WHATWG URL Standard normalizes backslash characters to forward slashes before parsing the authority component of special schemes (http, https, ftp, ws, wss), so https://evil\@trusted.com/ is parsed server-side via RFC-3986 as having host trusted.com (satisfying the allowlist) but the browser resolves it to https://evil/. (2) Slash-count normalization: WHATWG collapses any run of slashes after the scheme into exactly two, so https:/evil.com/ and https:///evil.com/ are treated as host-less by RFC-3986 (skipping host validation entirely) but resolve correctly to evil.com in browsers. (3) Element misclassification: UrlAttributeSanitizer routes href attributes to the link policy only when the element is exactly 'a'; the <area> element, which is equally navigable per HTML specification, fell through to the media policy - which typically permits data: URIs and may have no host allowlist. Affected packages are pkg:composer/symfony/html-sanitizer and pkg:composer/symfony/symfony across multiple version branches.
RemediationAI
Upgrade symfony/html-sanitizer to 6.4.40, 7.4.12, or 8.0.12 as appropriate for your branch; for the symfony/symfony metapackage, upgrade to 6.4.40. The upstream fix (commit d506b556d3d3906f3e8660ad82257ce87edbaac4, targeting branch 5.4) causes UrlSanitizer::sanitize() to reject any URL containing a backslash and any URL using a special scheme followed by a non-standard slash count before RFC-3986 parsing, and updates UrlAttributeSanitizer to apply the link policy to both <a> and <area> elements. If immediate upgrade is not possible, compensating controls include: (1) removing <area> from the list of allowed elements in your sanitizer configuration, which eliminates the element-misclassification bypass at the cost of disabling image map functionality; (2) adding a pre-sanitization normalization step that rejects or strips URLs containing backslashes or non-standard slash patterns after the scheme - note this may reject some technically valid but unusual URLs; (3) applying a strict Content Security Policy header that limits navigable URLs to known-safe origins, reducing the blast radius of any remaining bypass. See the advisory at https://github.com/symfony/symfony/security/advisories/GHSA-qc95-4862-92fh for full details.
Same weakness CWE-184 – Incomplete List of Disallowed Inputs
View allSame technique Authentication Bypass
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-44339
GHSA-qc95-4862-92fh