GHSA-2P49-HGCM-8545

GHSA-2P49-HGCM-8545 is a high-severity cross-site scripting (XSS) vulnerability in svgo (npm), affecting versions >= 1.0.0, < 2.8.3. It is fixed in 2.8.3, 3.3.4, 4.0.2.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

SVGO removeScripts plugin leaves some executable scripts intact

SVGO's removeScripts plugin (disabled by default) removes scripts from the SVG, however executable scripts were left intact in some cases. If a consumer relied on this plugin for sanitization and served them to users, these SVGs could open up doors to XSS.

Details

SVGO has a plugin for removing scripts from an SVG, which removes:

  • <script> elements
  • JavaScript URIs (v4 and v3 only)
  • on… event handlers (v4 and v3 only)

While SVGO is not a sanitization library, SVGO continues to maintain the plugin for those already using it for this purpose.

However, there were two problems:

  • SVGO did not check namespaced/prefixed script elements, for example if one declared an explicit prefix for the SVG namespace ( <svg:script>) instead of using the default namespace ( <script>), the <svg:script> tag would be left intact.
  • SVGO case sensitively matched JavaScript URIs, but it should've been case-insensitive.

Proof of Concept

import { optimize } from 'svgo';

/** Presume that this string was obtained in some other way, such as network. */
const original = `
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:uwu="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" version="1.1">
    <a uwu:href="JavaScript:(() =&gt; { alert(document.cookie) })();"><text y="30">uwu</text></a>
    <svg:script>
      alert(document.cookie);
    </svg:script>
  </svg>
`;

optimize(original, {
  plugins: ['removeScripts']
});
// Did not remove <svg:script> or uwu:href="JavaScript:…, still executed by browsers.

>= 3.0.0, <= 4.0.1

SVGO patched v4.0.2 and v3.3.4. Just upgrade the dependency using your preferred package manager! For example:

yarn up svgo

# or if SVGO is a nested dependency
yarn up -R svgo

The proposed fix is to improve our namespace-aware handling to explicitly act on the default namespace, SVG namespace, and XHTML namespace only. This handles all scripts that are executed by browsers, but will leave intact custom prefixes that happen to have an element called <*:script> which clients shouldn't treat as executable.

>= 2.0.0, <= 2.8.2

SVGO patched v2.8.3, however SVGO v2 explicitly only implements and documents that it will remove <script> elements and nothing more. It has the namespace aware handling for tags like <svg:script> or <xhtml:script>, but has not been updated to remove JavaScript URIs or event handlers like >= v3. If this is something you need, please upgrade to v4 or v3, or reach for one of the documented workarounds at the end.

>= 1.0.0, <= 1.3.2

SVGO v1 has been deprecated for a while now and won't be patched. Please upgrade to a more recent version! If something is preventing you from doing so, please reach out! We're happy to expand our migration guides or support you if you're having trouble.

Workarounds

If your motivation for enabling the plugin is SVG sanitization, consider reaching for a dedicated SVG sanitization tool and invoke it before passing the SVG to SVGO.

Impact

If you run SVGO on untrusted input (e.g., user uploads to a web application) and you depended on removeScripts, then some scripts may still be present. If that SVG was then opened directly by another user on the same domain, it could invoke scripts that could read local storage or cookies.

This may affect you if you have enabled one of the following:

SVGO Version Plugin Name
v4 removeScripts
v3 removeScriptElement
v2 removeScriptElement
v1 removeScriptElement

It's unlikely to impact users who just use SVGO locally on their own SVGs or in build pipelines.

Untrusted input is rendered as active markup in a victim's browser, which can run script in their session. Typical impact: session or credential theft, and actions taken as the user.

GHSA-2P49-HGCM-8545 has a CVSS score of 8.2 (High). The vector is network-reachable, no privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (2.8.3, 3.3.4, 4.0.2); upgrading removes the vulnerable code path.

Affected versions

svgo (>= 1.0.0, < 2.8.3) svgo (>= 3.0.0, < 3.3.4) svgo (>= 4.0.0, < 4.0.2)

Security releases

svgo → 2.8.3 (npm) svgo → 3.3.4 (npm) svgo → 4.0.2 (npm)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade the following packages to resolve this vulnerability:

svgo to 2.8.3 or later; svgo to 3.3.4 or later; svgo to 4.0.2 or later

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is GHSA-2P49-HGCM-8545? GHSA-2P49-HGCM-8545 is a high-severity cross-site scripting (XSS) vulnerability in svgo (npm), affecting versions >= 1.0.0, < 2.8.3. It is fixed in 2.8.3, 3.3.4, 4.0.2. Untrusted input is rendered as active markup in a victim's browser, which can run script in their session.
  2. How severe is GHSA-2P49-HGCM-8545? GHSA-2P49-HGCM-8545 has a CVSS score of 8.2 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of svgo are affected by GHSA-2P49-HGCM-8545? svgo (npm) versions >= 1.0.0, < 2.8.3 is affected.
  4. Is there a fix for GHSA-2P49-HGCM-8545? Yes. GHSA-2P49-HGCM-8545 is fixed in 2.8.3, 3.3.4, 4.0.2. Upgrade to this version or later.
  5. Is GHSA-2P49-HGCM-8545 exploitable, and should I be worried? Whether GHSA-2P49-HGCM-8545 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether GHSA-2P49-HGCM-8545 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix GHSA-2P49-HGCM-8545?
    • Upgrade svgo to 2.8.3 or later
    • Upgrade svgo to 3.3.4 or later
    • Upgrade svgo to 4.0.2 or later

Other vulnerabilities in svgo

Stop the waste.
Protect your environment with Kodem.