Affected versions
Symfony versions >=6.1, <6.4.40, >=7, <7.4.12, >=8, <8.0.12 of the Symfony HTML Sanitizer component are affected by this security issue.
The issue has been fixed in Symfony 6.4.40, 7.4.12, 8.0.12.
Description
Symfony (used by UrlSanitizer::sanitize() and therefore by every HtmlSanitizer config that allows links or media) accepts URLs that contain Unicode explicit-direction BiDi formatting characters: U+202A-U+202E (LRE / RLE / PDF / LRO / RLO) and U+2066-U+2069 (LRI / RLI / FSI / PDI). These characters are passed through unchanged into the href / src attributes produced by HtmlSanitizer. When the resulting HTML is rendered in a browser, the override characters reverse or alter the visual ordering of the URL text, so the displayed link can differ arbitrarily from the actual destination: a classic visual-spoofing / phishing primitive against viewers of sanitized content.
Resolution
UrlSanitizer::parse() now rejects URLs containing the explicit-direction BiDi formatting code points (U+202A-U+202E, U+2066-U+2069) before invoking the underlying URL parser. As an unrelated companion fix in the same patch, spaces inside path/query/fragment are now percent-encoded rather than rejected outright, while spaces in the scheme/authority remain rejected by the post-encoding whitespace check.
The patch for this issue is available here for branch 5.4.
Credits
We would like to thank Nicolas Grekas for reporting the issue and providing the fix.