CVE-2026-84370: svgo removeScripts Plugin XSS via Namespace and Control-Character Bypass
SVGO's removeScripts plugin could be tricked into leaving executable JavaScript links intact by using a namespace-prefixed SVG anchor or hiding a javascript: URL behind an embedded tab or newline…

The problem
The removeScripts plugin only checked unprefixed SVG <a> elements. An attacker could instead use <svg:a> (with the prefix bound to the SVG namespace) and the plugin would leave the executable href untouched.
Separately, the plugin matched the javascript: scheme against the raw attribute value. Browsers silently strip ASCII tab (U+0009), line-feed (U+000A), and carriage-return (U+000D) from a URL before parsing the scheme, so a value like java	script:alert(1) bypassed the string check but executed normally in-browser.
Proof of concept
A working proof-of-concept for CVE-2026-84370 in svgo, with the exact payload below.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<!-- Bypass 1: namespace-prefixed anchor -->
<svg:a href="javascript:alert(document.cookie)">
<text>click me</text>
</svg:a>
<!-- Bypass 2: tab character in scheme (	 = U+0009) -->
<a href="java	script:alert(document.cookie)">
<text>click me too</text>
</a>
</svg>Two root causes share CWE-184 (Incomplete List of Disallowed Inputs). First, the element-name check was a plain string comparison against a, so svg:a was never matched and its href was never inspected. Second, the scheme check compared the raw attribute string against javascript: without first normalizing out the control characters that browsers strip before URL parsing, so java script: sailed through.
The patch added namespace-aware element matching (accepting only anchors in the SVG or default namespace) and applied a strip of \t, \n, and \r from the href value before the scheme comparison, closing both paths.
The fix
Upgrade to svgo 2.8.4 (plugin: removeScriptElement), 3.3.5, or 4.1.0 (plugin: removeScripts). For hostile input, run a dedicated SVG sanitizer such as DOMPurify before passing the file to SVGO. Avoid serving user-controlled SVGs in an active same-origin context.
Related research
- high · 8.2svgo removeScripts Plugin XSS Bypass via Namespace Prefix and Case-Insensitive URI
- critical · 10CVE-2026-85061CVE-2026-85061: maplibre-gl XSS Sanitizer Bypass via Live NamedNodeMap Iteration
- highCVE-2026-54606CVE-2026-54606: suneditor Embed Plugin DOM XSS via External Script Element
- high · 8.7CVE-2026-55596CVE-2026-55596: @platejs/media Media Embed Stored XSS via Serialized Provider Metadata