mediumVulnerability

GHSA-55q2-fjhq-7xh7

### 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(currentNode)`. The detached subtree is not added to `DOMPurify.removed`, so the post-walk `IN_PLACE` neutralization cannot reach it. If the browser queued a resource event while the application constructed the detached dirty root, a descendant can therefore retain its handler and execute after sanitization. The hook only rejects the containing element and does not add or approve the event handler. DOMPurify's ordinary removal path de-arms the same queued event; only the hook-detachment early return skips the existing subtree neutralization. ### PoC Load the published `[email protected]` `dist/purify.js` before this script in Chromium: ```html <div id="result">not fired</div> <script> const root = document.createElement('div'); root.innerHTML = ` <footer> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="result.textContent = 'XSS after sanitize'"> </footer> <div>safe</div>`; DOMPurify.setConfig({ ALLOWED_TAGS: ['div', '#text', 'footer'], IN_PLACE: true }); DOMPurify.addHook('uponSanitizeElement', node => { if (node.tagName === 'FOOTER') node.remove(); }); DOMPurify.sanitize(root); document.body.append(root); </script> ``` `sanitize()` returns with no handler execution and the returned root contains only the safe `div`. After the event loop advances, the original image remains disconnected but its retained `

Properties

ghsa_id
GHSA-55q2-fjhq-7xh7
severity
medium
summary
DOMPurify: IN_PLACE hook removal leaves a detached subtree executable, causing XSS
cve_id
GHSA-55q2-fjhq-7xh7
is_ghsa_only
true
ghsa_published
2026-08-07T15:30:47Z
source_url
https://github.com/advisories/GHSA-55q2-fjhq-7xh7
ghsa_updated
2026-08-07T15:30:48Z

Related Entities (4)

VULNERABLE_TO (1)

[Software]npm/dompurify

AFFECTS (1)

[Software]npm/dompurify

HAS_WEAKNESS (1)

[Weakness]Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

REPORTED_BY (1)

[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

GHSA-55q2-fjhq-7xh7 — Ninja Signal Threat Intelligence | Ninja Signal