GHSA-v3wm-qf9p-c549 CVE-2026-48760
Symfony: HtmlSanitizer URL Parser Deny Gates Underinclusive: Percent-Encoded BiDi Marks and Unicode Whitespace Bypass Visual-Spoofing Defense
- Severity
- 5.3 / 10
- Medium · CVSS 4.0
- Exploit chance (EPSS)
- 0.34%
- Chance of exploitation in the next 30 days. Higher than 27.25% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-1007 Insufficient Visual Distinction of Homoglyphs Presented to User
- CWE-451 User Interface (UI) Misrepresentation of Critical Information
- Fix
- Available
- 2 packages have a fixed version
Description
Description
Symfony\Component\HtmlSanitizer\TextSanitizer\UrlSanitizer::parse() rejects URLs containing raw Unicode explicit-direction BiDi formatting characters (U+202A–U+202E, U+2066–U+2069) as a defense against visual-spoofing of the rendered href. The check covers only the raw UTF-8 forms of those code points: the percent-encoded forms (%E2%80%AE for U+202E, %E2%81%A6 for U+2066, etc.) are not matched by the deny regex, survive league/uri's parse/build cycle, and are re-emitted unchanged in the sanitized URL. Any downstream consumer that decodes the link before display — phishing-detection filters that compare urldecode($href) against a domain allow-list, audit-log dashboards that show a decoded form for readability, hover-tooltip previews, federated/syndicated content where the decoder lives on the consuming side — restores the BiDi character and the visual spoof that the original defense was filed to prevent.
The same UrlSanitizer::parse() carries an ASCII-only /\s/ whitespace check (no /u modifier) intended as a backstop against malformed URLs. Without the /u modifier, PCRE's \s matches only ASCII whitespace, so Unicode whitespace characters — NBSP (U+00A0), the zero-width no-break space / BOM (U+FEFF), line/paragraph separators (U+2028, U+2029), ogham space (U+1680), the U+2000–U+200A en/em quad family, narrow / medium / ideographic spaces (U+202F, U+205F, U+3000) and NEL (U+0085) — pass through unchanged in both raw and percent-encoded forms. In hostname positions they enable lookalike spoofs (example<NBSP>.com); in path/query/fragment they enable allow-list drift when a downstream consumer strips whitespace before comparison.
Resolution
UrlSanitizer::parse() now denies BiDi formatting marks together with Unicode whitespace and the zero-width no-break space, in both the raw input and the percent-decoded form of each parsed URL component (user, pass, host, path, query, fragment). ASCII space remains tolerated in path/query/fragment via the existing percent-encoding step.
The patches for this issue are available here for branch 6.4 (and forward-ported to 7.4, 8.0 and 8.1).
Credits
Symfony would like to thank Scott Arciszewski (Trail of Bits) for reporting the issue and Nicolas Grekas for providing the fix.
Affected versions
Packagist
| Package | Vulnerable | Fixed in |
|---|---|---|
| symfony/html-sanitizer | >= 6.1.0, < 6.4.41 |
6.4.41 |
| symfony/html-sanitizer | >= 7.0.0, < 7.4.13 |
7.4.13 |
| symfony/html-sanitizer | >= 8.0.0, < 8.0.13 |
8.0.13 |
| symfony/symfony | >= 6.1.0, < 6.4.41 |
6.4.41 |
| symfony/symfony | >= 7.0.0, < 7.4.13 |
7.4.13 |
| symfony/symfony | >= 8.0.0, < 8.0.13 |
8.0.13 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
symfony/html-sanitizer Packagist → 6.4.41
- composer
composer require symfony/html-sanitizer:^6.4.41
symfony/symfony Packagist → 6.4.41
- composer
composer require symfony/symfony:^6.4.41
Severity breakdown
CVSS 4.0 5.3
CVSS:4.0/AV:N/AC:L/AT:N/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
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- None
- User interaction
- Passive
- Confidentiality (vulnerable system)
- None
- Integrity (vulnerable system)
- None
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- Low
- Integrity (subsequent systems)
- Low
- Availability (subsequent systems)
- None
- Exploit maturity
- Not defined
- Scope
- X
CVSS 3.1 6.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- None
- User interaction
- Required
- Scope
- Changed
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Weakness
CWE-1007: Insufficient Visual Distinction of Homoglyphs Presented to User
The product displays information or identifiers to a user, but the display mechanism does not make it easy for the user to distinguish between visually similar or identical glyphs (homoglyphs), which may cause the user to misinterpret a glyph and perform an unintended, insecure action.
How to prevent it
- Implementation: Use a browser that displays Punycode for IDNs in the URL and status bars, or which color code various scripts in URLs. Due to the prominence of homoglyph attacks, several browsers now help safeguard against this attack via the use of Punycode. For example, Mozilla Firefox and Google Chrome will display IDNs as Punycode if top-level domains do not restrict which characters can be used in domain names or if labels mix scripts for different languages.
- Implementation: Use an email client that has strict filters and prevents messages that mix character sets to end up in a user's inbox. Certain email clients such as Google's GMail prevent the use of non-Latin characters in email addresses or in links contained within emails. This helps prevent homoglyph attacks by flagging these emails and redirecting them to a user's spam folder.
CWE-451: User Interface (UI) Misrepresentation of Critical Information
The user interface (UI) does not properly represent critical information to the user, allowing the information - or its source - to be obscured or spoofed. This is often a component in phishing attacks.
How to prevent it
- Implementation: Perform data validation (e.g. syntax, length, etc.) before interpreting the data.
- Architecture and Design: Create a strategy for presenting information, and plan for how to display unusual characters.
References
Packages
Other links
- github.com/symfony/symfony/security/advisories/GHSA-v3wm-qf9p-c549
- github.com/symfony/symfony/commit/b21a626fd90f5c12d2db432c629eed3e780ba2f8
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/html-sanitizer/…
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/symfony/CVE-202…
- symfony.com/cve-2026-48760
- github.com/symfony/symfony/releases/tag/v6.4.41
- github.com/symfony/symfony/releases/tag/v7.4.13
- github.com/symfony/symfony/releases/tag/v8.0.13
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-2v3c-qxhr-7vpv Symfony: Unbounded Recursion in the YAML Inline Lexer Lets a Single Document Crash the Process | High | Also affects symfony/symfony |
| GHSA-r925-mgvr-h9cc Symfony: ReDoS in HeaderUtils::split() Reachable Through the Cache-Control Request Header | High | Also affects symfony/symfony |
| GHSA-h5x3-xfc9-m39h Symfony: UrlGenerator Dot-Segment Encoding Skips Every Other Chained `../` or `./` → Generated URL Collapses Off-Route Under RFC 3986 Normalization | Medium | Also affects symfony/symfony |
| GHSA-rrj9-5q2j-4gvr Symfony: Mailomat Mailer Webhook Parser Reads the HMAC Algorithm from the Request: Signature Algorithm Downgrade | Medium | Also affects symfony/symfony |
| GHSA-38cx-cq6f-5755 Symfony: IpUtils::PRIVATE_SUBNETS Omits IPv6 Transition Forms (6to4, NAT64, Teredo, IPv4-compatible): SSRF Bypass in NoPrivateNetworkHttpClient | High | Also affects symfony/symfony |
| GHSA-6h46-9jf5-q59x Symfony: Security Firewall Bypass via failure_forward Subrequest: Unauthenticated Access to access_control-Protected GET Routes | High | Also affects symfony/symfony |
| GHSA-x5qj-865h-mgvm Symfony: HtmlSanitizer UrlAttributeSanitizer Misses URL Attributes | Medium | Also affects symfony/html-sanitizer |
| GHSA-fqc7-9xjw-jrh3 SymfonyRuntime CVE-2024-50340 Patch Bypass: Web Requests Can Still Set APP_ENV/APP_DEBUG via parse_str/SAPI Argv Mismatch | Critical | Also affects symfony/symfony |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor