dompurify

Ecosystem: npm

Downloads: 321.25 Mln

Vulnerabilities from the last (months)
  • 3CriticalAffects 3 versions
  • 4HighAffects 6 versions
  • 0MediumAffects 0 versions
  • 20ModerateAffects 22 versions
  • 7LowAffects 7 versions
Severity distribution (all time)
34vulnerabilities
  • 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.

Vulnerabilities affecting dompurify
IDSeveritySummaryAffected versionsPublishedSource
GHSA-c6gr-qvv4-5v3fLowDOMPurify: 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
  • < 3.4.17
GitHub (opens in a new tab)
GHSA-cg2g-xh64-v4q7CriticalDOMPurify 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`
  • >= 3.4.4, < 3.4.17
GitHub (opens in a new tab)
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)### 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
  • < 3.4.17
GitHub (opens in a new tab)
GHSA-6688-9rhm-gjv2LowDOMPurify: 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
  • < 3.4.16
GitHub (opens in a new tab)
GHSA-p98j-92pf-mc4pLowDOMPurify: 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
  • >= 3.4.13, < 3.4.16
GitHub (opens in a new tab)
GHSA-55q2-fjhq-7xh7ModerateDOMPurify: 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
  • < 3.4.13
GitHub (opens in a new tab)
GHSA-jxrp-r7gx-q4j8ModerateDuplicate 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.
  • <= 3.4.11
GitHub (opens in a new tab)
GHSA-c2j3-45gr-mqc4LowDOMPurify: `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
  • < 3.4.12
GitHub (opens in a new tab)
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)## 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
  • < 3.4.11
GitHub (opens in a new tab)
GHSA-76mc-f452-cxcmModerateDOMPurify: 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
  • < 3.4.7
GitHub (opens in a new tab)
  • GHSA-c6gr-qvv4-5v3fLow
    DOMPurify: 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-v4q7Critical
    DOMPurify 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-j5jrHigh
    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)
    • < 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-gjv2Low
    DOMPurify: 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-mc4pLow
    DOMPurify: 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-7xh7Moderate
    DOMPurify: 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-q4j8Moderate
    Duplicate 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-mqc4Low
    DOMPurify: `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-8882Moderate
    DOMPurify: 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-cxcmModerate
    DOMPurify: 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

Showing 1-10 of 34 vulnerabilities