Symfony's HtmlSanitizer UrlAttributeSanitizer Omits action/formaction/poster/cite — `javascript`: URI Survives Sanitization (XSS)
Date: 2026-05
Affected: composer/symfony/symfony, composer/symfony/symfony, composer/symfony/symfony
Attack vector: xss
Category: vulnerability-disclosure
Severity: Low
CVE: CVE-2026-45753
CWE: CWE-184
CWE-79

### Description `symfony/html-sanitizer` lets applications sanitise untrusted HTML. `UrlAttributeSanitizer` is the visitor responsible for validating URL-valued attributes and stripping dangerous schemes from them; it runs on every element regardless of configuration. Whether an attribute is *kept* is decided by the element/attribute allow-list; validating the *scheme* of a URL attribute is solely `UrlAttributeSanitizer`'s responsibility. `UrlAttributeSanitizer::getSupportedAttributes()` returned only `['src', 'href', 'lowsrc', 'background', 'ping']`. The HTML URL-valued attributes `action` (`<form>`), `formaction` (`<button>`, `<input type=image>`), `poster` (`<video>`) and `cite` (`<blockquote>`, `<q>`, `<del>`, `<ins>`) were missing from that list, so `DomVisitor` never invoked scheme validation for them. As a result, when a configuration admits one of those attributes, a `javascript:` URI in it survived sanitisation. ### Conditions for exploitation `allowSafeElements()` is **not** affected: `<form>` and the `formaction` attribute are both flagged unsafe in `W3CReference`, and `allowElement('form')` resets the element's attribute list. Reaching the vulnerable attributes requires a deliberately permissive configuration, for example: * `<form>` + `action`: `allowElement('form', '*')`, `allowElement('form', ['action', …])`, `allowElement('form')->allowAttribute('action', 'form')`, or the `allowStaticElements()` preset (whose docblock already warns the output "may still c


Mitigations:

Architectural layers (MAESTRO):