dompurify
Ecosystem: npm
Downloads: 321.25 Mln
- 3CriticalAffects 3 versions
- 4HighAffects 6 versions
- 0MediumAffects 0 versions
- 20ModerateAffects 22 versions
- 7LowAffects 7 versions
- Critical3 (8.8%)
- High4 (11.8%)
- Medium0 (0.0%)
- Moderate20 (58.8%)
- Low7 (20.6%)
Monthly breakdown
- Critical
- High
- Medium
- Moderate
- Low
- 4 vulnerabilities
- Critical: 1
- High: 1
- Medium: 0
- Moderate: 0
- Low: 2
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 0
- Low: 1
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 2 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 1
- 9 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 5
- Low: 3
- 6 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 6
- Low: 0
- 3 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 3
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 2 vulnerabilities
- Critical: 1
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 1
- High: 0
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
Vulnerabilities (34)
Known vulnerabilities affecting dompurify, based on data from OSV.
| ID | Severity | Summary | Affected versions | Published | Source |
|---|---|---|---|---|---|
| GHSA-c6gr-qvv4-5v3f | Low | DOMPurify: SMIL attributeName=href guard is skipped when PARSER_MEDIA_TYPE is application/xhtml+xml### Summary DOMPurify drops `attributeName` attributes whose value contains `href`, so an allowed `<animate>` or `<set>` can't rewrite a link's href after sanitizing. The check compares the attribute name after `transformCaseFunc`, and that function doesn't lowercase in XHTML mode. In XHTML the attribute is spelled `attributeName`, so the comparison with `"attributename"` never matches and the guard does nothing. An app that uses `PARSER_MEDIA_TYPE: 'application/xhtml+xml'` and allows `animate` and `attributeName` will keep `<animate attributeName="href" values="x;javascript:alert(1)">`. Cli |
| GitHub (opens in a new tab) | |
| GHSA-cg2g-xh64-v4q7 | Critical | DOMPurify SAFE_FOR_TEMPLATES bypass: split template expressions survive in attached shadow root content on DOM output modes## Summary When DOMPurify is configured with `SAFE_FOR_TEMPLATES: true` together with a DOM-returning mode (`RETURN_DOM: true`, `RETURN_DOM_FRAGMENT: true`, or `IN_PLACE: true`), template expressions such as `{{...}}`, `${...}`, and `<%...%>` survive sanitization inside the text content of an attached shadow root. The post-walk safety net `_scrubTemplateExpressions` (`src/purify.ts:1717`) was extended to recurse into `<template>.content`, but it never recurses into attached shadow roots. An attacker who can supply a DOM node carrying a shadow root (the `IN_PLACE` and shadow-aware `RETURN_DOM` |
| GitHub (opens in a new tab) | |
| GHSA-mrv2-3pqr-j5jr | High | DOMPurify IN_PLACE: hook that removes a parent or sibling leaves the detached subtree's event handlers armed (incomplete fix for GHSA-p98j-92pf-mc4p)### Summary The 3.4.16 fix for GHSA-p98j-92pf-mc4p only covers a hook that removes the node it was called for. If an `IN_PLACE` hook removes a different node, like the current node's parent or a sibling that has not been visited yet, that subtree is never walked or neutralized. Event handlers in it stay on the elements, and an `<img onerror>` that was already loading fires after `sanitize()` returns. The README says: "Nodes that a hook detaches from the tree ... are treated as removed. In IN_PLACE mode their subtree is neutralized inline, so an `<img onload>` that was already loading when yo |
| GitHub (opens in a new tab) | |
| GHSA-6688-9rhm-gjv2 | Low | DOMPurify: IN_PLACE returns a force-removed rawtext root whose text carries attacker markup — pure HTML reparse executes## Environment - dompurify 3.4.15 (current npm release); reproduced independently on jsdom 30.0.1 and 29.1.1 (Node.js 20.x / 26.x) - Config: `DOMPurify.sanitize(node, { IN_PLACE: true })` on a Node input; `SAFE_FOR_XML` at its default (`true`) ## Summary The 3.4.9 fix for the IN_PLACE detached-root class added two protections on the IN_PLACE return path: a fail-closed `TypeError` in `_forceRemove` when a node selected for removal cannot be detached, and a `_neutralizeSubtree` pass (`dist/purify.js` line 1336) that strips non-allowlisted **attributes** from removed subtrees. Both miss the r |
| GitHub (opens in a new tab) | |
| GHSA-p98j-92pf-mc4p | Low | DOMPurify: IN_PLACE: node-removing afterSanitize hook leaves detached subtree event handlers armed, causing DOM XSS## Summary In `IN_PLACE` mode DOMPurify sanitizes the caller's live DOM subtree directly. To close a known hazard (GHSA-55q2-fjhq-7xh7), the library neutralizes any node a hook detaches during sanitization by stripping its subtree's non-allow-listed attributes, but this neutralization is wired only into the `beforeSanitizeElements` and `uponSanitizeElement` hook sites. An `afterSanitizeElements` or `afterSanitizeAttributes` hook that removes a non-root element (a documented, supported pattern) detaches that element's subtree with no neutralization, so descendant `on*` handlers remain armed on |
| GitHub (opens in a new tab) | |
| GHSA-55q2-fjhq-7xh7 | Moderate | DOMPurify: IN_PLACE hook removal leaves a detached subtree executable, causing XSS### Summary During `IN_PLACE` sanitization, a hook that removes an element can leave that element's detached descendants executable. A descendant image can retain its attacker-provided `onload` handler and fire after `sanitize()` returns, even though the returned root is clean and the image remains disconnected from the document. ### Details In DOMPurify 3.4.12, `_sanitizeElements()` in `src/purify.ts:1862-1904` runs the `beforeSanitizeElements` or `uponSanitizeElement` hook and returns immediately when the hook detached the current node. The return does not call `_neutralizeSubtree(current |
| GitHub (opens in a new tab) | |
| GHSA-jxrp-r7gx-q4j8 | Moderate | Duplicate Advisory: DOMPurify: `CUSTOM_ELEMENT_HANDLING` bypasses `afterSanitizeElements` for allowed custom elements.## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-c2j3-45gr-mqc4. This link is maintained to preserve external references. ## Original Description DOMPurify before 3.4.12 fails to execute afterSanitizeElements hook for custom elements allowed via CUSTOM_ELEMENT_HANDLING.tagNameCheck, allowing attributes to bypass application security policies. Attackers can preserve sensitive attributes on custom elements that later re-inject them into innerHTML sinks, creating second-order XSS gadgets. |
| GitHub (opens in a new tab) | |
| GHSA-c2j3-45gr-mqc4 | Low | DOMPurify: `CUSTOM_ELEMENT_HANDLING` bypasses `afterSanitizeElements` for allowed custom elements.## Summary There is a possible hook-policy inconsistency in DOMPurify 3.4.11 involving `CUSTOM_ELEMENT_HANDLING`. When a custom element is allowed via `CUSTOM_ELEMENT_HANDLING.tagNameCheck`, it appears that the element does not go through `afterSanitizeElements` in the same way as a normal element. As a result, an application that relies on `afterSanitizeElements` as a security policy layer to strip sensitive attributes from all elements may see those attributes removed from normal elements but preserved on allowed custom elements. This does not appear to be a direct DOMPurify XSS or a case |
| GitHub (opens in a new tab) | |
| GHSA-cmwh-pvxp-8882 | Moderate | DOMPurify: Permanent `ALLOWED_ATTR` pollution via `setConfig()` bypassing the hook clone-guard (incomplete fix of the 3.4.7 hook-pollution patch)## Summary DOMPurify 3.4.7 shipped a security fix ("permanent hook pollution") that makes a registered `uponSanitizeAttribute` hook's mutation of `data.allowedAttributes` **non-persistent** — so allowing an attribute for one element does not leak into later `sanitize()` calls. The fix clones `ALLOWED_ATTR` inside `_parseConfig`. That guard is **silently bypassed whenever the application uses the persistent-config API `DOMPurify.setConfig()`.** `setConfig()` sets the module flag `SET_CONFIG = true`, which causes `sanitize()` to **skip `_parseConfig` entirely** — and the clone-guard lives insi |
| GitHub (opens in a new tab) | |
| GHSA-76mc-f452-cxcm | Moderate | DOMPurify: Hook mutation of `data.allowedTags` / `data.allowedAttributes` permanently pollutes `DEFAULT_ALLOWED_TAGS` / `DEFAULT_ALLOWED_ATTR`# Hook mutation of `data.allowedTags` / `data.allowedAttributes` permanently pollutes `DEFAULT_ALLOWED_TAGS` / `DEFAULT_ALLOWED_ATTR` **CWE**: CWE-501 (Trust Boundary Violation — hook-scoped mutation leaks to global default sets) via CWE-693 (Protection Mechanism Failure — the default allow-list is silently widened for all subsequent sanitize calls) ## Summary The `data.allowedTags` and `data.allowedAttributes` fields passed to `uponSanitizeElement` and `uponSanitizeAttribute` hooks are **direct references** to the library's live `ALLOWED_TAGS` / `ALLOWED_ATTR` sets. For sanitize calls that |
| GitHub (opens in a new tab) |
- GHSA-c6gr-qvv4-5v3fLowDOMPurify: SMIL attributeName=href guard is skipped when PARSER_MEDIA_TYPE is application/xhtml+xml
< 3.4.17
### Summary DOMPurify drops `attributeName` attributes whose value contains `href`, so an allowed `<animate>` or `<set>` can't rewrite a link's href after sanitizing. The check compares the attribute name after `transformCaseFunc`, and that function doesn't lowercase in XHTML mode. In XHTML the attribute is spelled `attributeName`, so the comparison with `"attributename"` never matches and the guard does nothing. An app that uses `PARSER_MEDIA_TYPE: 'application/xhtml+xml'` and allows `animate` and `attributeName` will keep `<animate attributeName="href" values="x;javascript:alert(1)">`. Cli
CVE: CVE-2026-116802
- GHSA-cg2g-xh64-v4q7CriticalDOMPurify SAFE_FOR_TEMPLATES bypass: split template expressions survive in attached shadow root content on DOM output modes
>= 3.4.4, < 3.4.17
## Summary When DOMPurify is configured with `SAFE_FOR_TEMPLATES: true` together with a DOM-returning mode (`RETURN_DOM: true`, `RETURN_DOM_FRAGMENT: true`, or `IN_PLACE: true`), template expressions such as `{{...}}`, `${...}`, and `<%...%>` survive sanitization inside the text content of an attached shadow root. The post-walk safety net `_scrubTemplateExpressions` (`src/purify.ts:1717`) was extended to recurse into `<template>.content`, but it never recurses into attached shadow roots. An attacker who can supply a DOM node carrying a shadow root (the `IN_PLACE` and shadow-aware `RETURN_DOM`
CVE: CVE-2026-116804
- GHSA-mrv2-3pqr-j5jrHighDOMPurify IN_PLACE: hook that removes a parent or sibling leaves the detached subtree's event handlers armed (incomplete fix for GHSA-p98j-92pf-mc4p)
< 3.4.17
### Summary The 3.4.16 fix for GHSA-p98j-92pf-mc4p only covers a hook that removes the node it was called for. If an `IN_PLACE` hook removes a different node, like the current node's parent or a sibling that has not been visited yet, that subtree is never walked or neutralized. Event handlers in it stay on the elements, and an `<img onerror>` that was already loading fires after `sanitize()` returns. The README says: "Nodes that a hook detaches from the tree ... are treated as removed. In IN_PLACE mode their subtree is neutralized inline, so an `<img onload>` that was already loading when yo
CVE: CVE-2026-116803
- GHSA-6688-9rhm-gjv2LowDOMPurify: IN_PLACE returns a force-removed rawtext root whose text carries attacker markup — pure HTML reparse executes
< 3.4.16
## Environment - dompurify 3.4.15 (current npm release); reproduced independently on jsdom 30.0.1 and 29.1.1 (Node.js 20.x / 26.x) - Config: `DOMPurify.sanitize(node, { IN_PLACE: true })` on a Node input; `SAFE_FOR_XML` at its default (`true`) ## Summary The 3.4.9 fix for the IN_PLACE detached-root class added two protections on the IN_PLACE return path: a fail-closed `TypeError` in `_forceRemove` when a node selected for removal cannot be detached, and a `_neutralizeSubtree` pass (`dist/purify.js` line 1336) that strips non-allowlisted **attributes** from removed subtrees. Both miss the r
CVE: CVE-2026-109345
- GHSA-p98j-92pf-mc4pLowDOMPurify: IN_PLACE: node-removing afterSanitize hook leaves detached subtree event handlers armed, causing DOM XSS
>= 3.4.13, < 3.4.16
## Summary In `IN_PLACE` mode DOMPurify sanitizes the caller's live DOM subtree directly. To close a known hazard (GHSA-55q2-fjhq-7xh7), the library neutralizes any node a hook detaches during sanitization by stripping its subtree's non-allow-listed attributes, but this neutralization is wired only into the `beforeSanitizeElements` and `uponSanitizeElement` hook sites. An `afterSanitizeElements` or `afterSanitizeAttributes` hook that removes a non-root element (a documented, supported pattern) detaches that element's subtree with no neutralization, so descendant `on*` handlers remain armed on
CVE: CVE-2026-109344
- GHSA-55q2-fjhq-7xh7ModerateDOMPurify: IN_PLACE hook removal leaves a detached subtree executable, causing XSS
< 3.4.13
### Summary During `IN_PLACE` sanitization, a hook that removes an element can leave that element's detached descendants executable. A descendant image can retain its attacker-provided `onload` handler and fire after `sanitize()` returns, even though the returned root is clean and the image remains disconnected from the document. ### Details In DOMPurify 3.4.12, `_sanitizeElements()` in `src/purify.ts:1862-1904` runs the `beforeSanitizeElements` or `uponSanitizeElement` hook and returns immediately when the hook detached the current node. The return does not call `_neutralizeSubtree(current
CVE: CVE-2026-75838
- GHSA-jxrp-r7gx-q4j8ModerateDuplicate Advisory: DOMPurify: `CUSTOM_ELEMENT_HANDLING` bypasses `afterSanitizeElements` for allowed custom elements.
<= 3.4.11
## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-c2j3-45gr-mqc4. This link is maintained to preserve external references. ## Original Description DOMPurify before 3.4.12 fails to execute afterSanitizeElements hook for custom elements allowed via CUSTOM_ELEMENT_HANDLING.tagNameCheck, allowing attributes to bypass application security policies. Attackers can preserve sensitive attributes on custom elements that later re-inject them into innerHTML sinks, creating second-order XSS gadgets.
- GHSA-c2j3-45gr-mqc4LowDOMPurify: `CUSTOM_ELEMENT_HANDLING` bypasses `afterSanitizeElements` for allowed custom elements.
< 3.4.12
## Summary There is a possible hook-policy inconsistency in DOMPurify 3.4.11 involving `CUSTOM_ELEMENT_HANDLING`. When a custom element is allowed via `CUSTOM_ELEMENT_HANDLING.tagNameCheck`, it appears that the element does not go through `afterSanitizeElements` in the same way as a normal element. As a result, an application that relies on `afterSanitizeElements` as a security policy layer to strip sensitive attributes from all elements may see those attributes removed from normal elements but preserved on allowed custom elements. This does not appear to be a direct DOMPurify XSS or a case
CVE: CVE-2026-66010
- GHSA-cmwh-pvxp-8882ModerateDOMPurify: Permanent `ALLOWED_ATTR` pollution via `setConfig()` bypassing the hook clone-guard (incomplete fix of the 3.4.7 hook-pollution patch)
< 3.4.11
## Summary DOMPurify 3.4.7 shipped a security fix ("permanent hook pollution") that makes a registered `uponSanitizeAttribute` hook's mutation of `data.allowedAttributes` **non-persistent** — so allowing an attribute for one element does not leak into later `sanitize()` calls. The fix clones `ALLOWED_ATTR` inside `_parseConfig`. That guard is **silently bypassed whenever the application uses the persistent-config API `DOMPurify.setConfig()`.** `setConfig()` sets the module flag `SET_CONFIG = true`, which causes `sanitize()` to **skip `_parseConfig` entirely** — and the clone-guard lives insi
CVE: CVE-2026-65898
- GHSA-76mc-f452-cxcmModerateDOMPurify: Hook mutation of `data.allowedTags` / `data.allowedAttributes` permanently pollutes `DEFAULT_ALLOWED_TAGS` / `DEFAULT_ALLOWED_ATTR`
< 3.4.7
# Hook mutation of `data.allowedTags` / `data.allowedAttributes` permanently pollutes `DEFAULT_ALLOWED_TAGS` / `DEFAULT_ALLOWED_ATTR` **CWE**: CWE-501 (Trust Boundary Violation — hook-scoped mutation leaks to global default sets) via CWE-693 (Protection Mechanism Failure — the default allow-list is silently widened for all subsequent sanitize calls) ## Summary The `data.allowedTags` and `data.allowedAttributes` fields passed to `uponSanitizeElement` and `uponSanitizeAttribute` hooks are **direct references** to the library's live `ALLOWED_TAGS` / `ALLOWED_ATTR` sets. For sanitize calls that
CVE: CVE-2026-65902