CVE-2026-12316
Overview
Background
- `Sanitizer`
- Gecko’s implementation of the HTML Sanitizer API that strips unsafe markup and attributes from untrusted DOM subtrees.
- `RemoveJavascriptNavigationURLAttribute`
- a sanitizer helper that identifies navigation-URL attributes (like
href) sojavascript:values can be neutralized. - `xlink:href`
- the legacy XLink-namespaced form of
hrefused by SVG and other XML content to specify link targets. - `StringEndsWith`
- a Gecko string utility that tests whether a string ends with a given suffix.
Root Cause Analysis
The vulnerable path is the attribute-name check inside RemoveJavascriptNavigationURLAttribute, which decided whether a given attribute was a navigation-URL attribute eligible for javascript: removal.
The invariant that was violated is that all href-equivalent attribute spellings must be recognized, but the old code enumerated only two exact literals, href and xlink:href, via value.EqualsLiteral. Any other prefixed spelling of a namespaced href attribute — a :href attribute carried under a different or attacker-chosen prefix — failed both equality checks and was therefore treated as a non-navigation attribute and left untouched.
The fix replaces the second exact-match check with StringEndsWith(value, u":href"_ns), so any attribute name ending in :href (regardless of the prefix) is now recognized and its javascript: value is stripped. This works because the sanitizer no longer depends on a hardcoded prefix and instead matches the structural suffix that all namespaced href attributes share.
xlink:href) instead of by their common :href suffix, so alternately prefixed href attributes bypassed sanitization; the fix generalizes the check with StringEndsWith(value, u":href"_ns).Attack Path
- Craft namespaced navigation attribute
An attacker prepares markup whose link target uses an href attribute under a prefix other than the literal
xlink(any spelling ending in:href). - Embed a script URL
The attacker sets that attribute’s value to a
javascript:navigation URL. - Route through the Sanitizer The content is passed to the Sanitizer API, which the application relies on to remove dangerous navigation URLs.
- Slip past the literal check
RemoveJavascriptNavigationURLAttributefails to match the non-xlink:hrefspelling and leaves thejavascript:value in place. - Trigger execution
When the surviving link is activated or navigated, the
javascript:URL runs, defeating the sanitizer mitigation.
Impact Assessment
javascript: navigation URL that the sanitizer was expected to strip, enabling script execution in the context of the page that trusted the sanitized output. This occurs in the content process within the origin embedding the sanitized markup. The precondition is that the target application uses the Sanitizer to clean attacker-influenced markup and that the attacker can control an href attribute’s namespace prefix.Files Changed
dom/security/sanitizer/Sanitizer.cpp
Audit Directions
- Exact-literal allow/deny checks on attribute namesLook for sanitizer or security logic that enumerates specific namespaced attribute spellings with
EqualsLiteral, which can miss alternately prefixed equivalents. - Namespaced attribute matchingAudit places that assume a fixed prefix (like
xlink) for XML/SVG attributes rather than matching by local name or suffix. - Navigation-URL removal coverageVerify every code path that strips
javascript:or other dangerous URLs covers all attribute spellings that can carry a navigable target.
Patch
diff --git a/dom/security/sanitizer/Sanitizer.cpp b/dom/security/sanitizer/Sanitizer.cpp
index 8fc0804a7a0..4e120a8d8fd 100644
--- a/dom/security/sanitizer/Sanitizer.cpp
+++ b/dom/security/sanitizer/Sanitizer.cpp
@@ -1650,7 +1650,7 @@ static bool RemoveJavascriptNavigationURLAttribute(Element* aElement,
return false;
}
- return value.EqualsLiteral("href") || value.EqualsLiteral("xlink:href");
+ return value.EqualsLiteral("href") || StringEndsWith(value, u":href"_ns);
}
return false;