CVE-2024-47875 - Breaking Down the DOMPurify mXSS Vulnerability (With Exploit Example and Fix!)

If you’re building web apps in 2024, chances are you use tools to keep your users safe—especially against XSS (Cross-Site Scripting). One of the most popular tools for this job is DOMPurify: a JavaScript library to clean up user content so attackers can’t run malicious code on your site.

But in May 2024, a serious security hole was found in DOMPurify: CVE-2024-47875. This vulnerability made it possible for attackers to bypass DOMPurify’s XSS protection using a technique called *mathematical XSS* (mXSS), specifically through nested HTML elements.

Let’s walk through what happened, how the exploit works, and how to fix it.

What is DOMPurify?

DOMPurify is a JavaScript library that "sanitizes" HTML—removing anything that might be dangerous, like script tags and weird attributes. Developers rely on this library so they can safely show user content (like blog comments, forum posts, or chat messages) without worrying someone might sneak in malicious code.

It’s free, open source, and used by thousands of websites—so when something goes wrong, it matters.

What is mXSS?

*mXSS* stands for "mutation XSS." Browsers can sometimes change (“mutate”) how they interpret funky HTML code, re-interpreting it in unintended ways. Attackers learned to use this to slip malicious content past sanitizers—even ones that seem very strict.

In DOMPurify before versions 2.5. and 3.1.3, there was a bug where *nesting* certain tags could trigger this mutated XSS.

DOMPurify would clean it…but not enough.

- When the browser displayed the sanitized HTML, it could “mutate” it into something dangerous—reintroducing XSS.

Suppose your site runs something like this to clean input (using a vulnerable DOMPurify version)

import DOMPurify from 'dompurify';

function sanitizeUserInput(inputHtml) {
  return DOMPurify.sanitize(inputHtml);
}

If the attacker submits this evil HTML input

<math><annotation-xml encoding="application/xhtml+xml"><svg><foreignObject><iframe srcdoc="<img src=x onerror=alert(Hacked!)>" /></foreignObject></svg></annotation-xml></math>

The input looks strange, but browsers allow math, svg, and foreignObject elements.

2. Old DOMPurify tries to clean it, but the weird nesting confuses both DOMPurify and some browsers, so some dangerous code could slip through.
3. When the browser renders the result, the payload <img src=x onerror=alert('Hacked!')> runs — popping up an alert (or worse, stealing your data).

Try this unsafe snippet (with old DOMPurify)

const input = &lt;math&gt;&lt;annotation-xml encoding=&quot;application/xhtml+xml&quot;&gt;&lt;svg&gt;&lt;foreignObject&gt;&lt;iframe srcdoc=&quot;&lt;img src=x onerror=alert(&#039;Hacked!&#039;)&gt;&quot; /&gt;&lt;/foreignObject&gt;&lt;/svg&gt;&lt;/annotation-xml&gt;&lt;/math&gt;;
document.body.innerHTML = sanitizeUserInput(input);
// Click-to-run alert if running a vulnerable version!

Upgrade to DOMPurify 2.5. or 3.1.3 or later – and the alert won’t show. The payload gets cleaned out.

References and Credits

- Original CVE entry: NIST CVE-2024-47875
- DOMPurify Release Notes – 2.5.
- DOMPurify Official Repo
- XSS Game: mXSS explained (great background on mutation XSS)
- Vulnerability report thread

Update DOMPurify ASAP!

If you use DOMPurify, make sure you are using at least 2.5. (if on 2.x) or 3.1.3 (if on 3.x+):

npm install dompurify@^2.5.
# OR
npm install dompurify@^3.1.3

And yes, it’s that simple. No API changes—just update!

CVE-2024-47875 allowed attackers to bypass DOMPurify with nested tags (mXSS).

- If you build web apps and rely on DOMPurify, upgrading is critical to keep your users safe from clever XSS attacks.

Patch fast; it’s a one-line update.

Stay safe and keep your dependencies up-to-date! If you want to dive deeper, check the issue on GitHub or the full commit history.

Timeline

Published on: 10/11/2024 15:15:05 UTC
Last modified on: 10/15/2024 12:58:51 UTC