CVE-2026-49459
DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
CVE-2026-49459 is a medium vulnerability (CVSS 6.1) in Cure53 Dompurify, published June 5, 2019. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.36%, the 30th percentile. Fixed in handlebars 3.0.8.
- Severity
- 6.1 MediumCVSS 3.1, CVE List
- Exploit chance
- 0.36%EPSS, 30th percentile
- Exploitation
- None knownNot on CISA’s or ENISA’s lists
- Fixed in
3.0.8handlebars +42 more
Description
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
handlebarsnpm | before 3.0.8 | 3.0.8 |
handlebarsnpm | 4.0.0 up to 4.5.2 | 4.5.2 |
handlebarsnpm | 4.0.0 up to 4.5.3 | 4.5.3 |
handlebarsnpm | 4.1.0 up to 4.1.2 | 4.1.2 |
handlebarsnpm | 4.0.0 up to 4.0.14 | 4.0.14 |
handlebarsnpm | before 3.0.7 | 3.0.7 |
dompurifynpm | through 3.4.5 | 3.4.6 |
handlebarsTuxCare:npm | 1.3.0-tuxcare.0 up to 1.3.0-tuxcare.1, plus listed versions 1.3.0 | 1.3.0-tuxcare.1 |
handlebarsTuxCare:npm | 1.0.12-tuxcare.0 up to 1.0.12-tuxcare.2, plus listed versions 1.0.121.0.12-tuxcare.1 | 1.0.12-tuxcare.2 |
dompurifyTuxCare:npm | 3.1.6-tuxcare.0 up to 3.1.6-tuxcare.4, plus listed versions 3.1.63.1.6-tuxcare.13.1.6-tuxcare.23.1.6-tuxcare.3 | 3.1.6-tuxcare.4 |
Show 33 moreShow less
| Package | Affected | Fixed |
|---|---|---|
dompurifyTuxCare:npm From an advisory covering 2 CVEs | 3.2.3-tuxcare.0 up to 3.2.3-tuxcare.2, plus listed versions 3.2.33.2.3-tuxcare.1 | 3.2.3-tuxcare.2 |
dompurifyTuxCare:npm From an advisory covering 3 CVEs | 3.2.7-tuxcare.0 up to 3.2.7-tuxcare.2, plus listed versions 3.2.73.2.7-tuxcare.1 | 3.2.7-tuxcare.2 |
dompurifyTuxCare:npm From an advisory covering 10 CVEs | 2.3.0-tuxcare.0 up to 2.3.0-tuxcare.5, plus listed versions 2.3.02.3.0-tuxcare.12.3.0-tuxcare.22.3.0-tuxcare.32.3.0-tuxcare.4 | 2.3.0-tuxcare.5 |
dompurifyTuxCare:npm From an advisory covering 11 CVEs | 3.0.3-tuxcare.0 up to 3.0.3-tuxcare.5, plus listed versions 3.0.33.0.3-tuxcare.13.0.3-tuxcare.23.0.3-tuxcare.33.0.3-tuxcare.4 | 3.0.3-tuxcare.5 |
dompurifyTuxCare:npm From an advisory covering 8 CVEs | 2.4.7-tuxcare.0 up to 2.4.7-tuxcare.5, plus listed versions 2.4.72.4.7-tuxcare.12.4.7-tuxcare.22.4.7-tuxcare.32.4.7-tuxcare.4 | 2.4.7-tuxcare.5 |
dompurifyTuxCare:npm From an advisory covering 11 CVEs | 2.4.3-tuxcare.0 up to 2.4.3-tuxcare.8, plus listed versions 2.4.32.4.3-tuxcare.12.4.3-tuxcare.22.4.3-tuxcare.32.4.3-tuxcare.42.4.3-tuxcare.52.4.3-tuxcare.62.4.3-tuxcare.7 | 2.4.3-tuxcare.8 |
dompurifyTuxCare:npm From an advisory covering 7 CVEs | 2.5.8-tuxcare.0 up to 2.5.8-tuxcare.7, plus listed versions 2.5.82.5.8-tuxcare.12.5.8-tuxcare.22.5.8-tuxcare.32.5.8-tuxcare.42.5.8-tuxcare.52.5.8-tuxcare.6 | 2.5.8-tuxcare.7 |
dompurifyTuxCare:npm From an advisory covering 6 CVEs | 3.4.5-tuxcare.0 up to 3.4.5-tuxcare.2, plus listed versions 3.4.53.4.5-tuxcare.1 | 3.4.5-tuxcare.2 |
dompurifyTuxCare:npm From an advisory covering 6 CVEs | 2.0.8-tuxcare.0 up to 2.0.8-tuxcare.2, plus listed versions 2.0.82.0.8-tuxcare.1 | 2.0.8-tuxcare.2 |
dompurifyTuxCare:npm From an advisory covering 5 CVEs | 3.3.3-tuxcare.0 up to 3.3.3-tuxcare.2, plus listed versions 3.3.33.3.3-tuxcare.1 | 3.3.3-tuxcare.2 |
dompurifyTuxCare:npm From an advisory covering 10 CVEs | 3.2.6-tuxcare.0 up to 3.2.6-tuxcare.2, plus listed versions 3.2.63.2.6-tuxcare.1 | 3.2.6-tuxcare.2 |
dompurifyTuxCare:npm From an advisory covering 12 CVEs | 2.3.3-tuxcare.0 up to 2.3.3-tuxcare.3, plus listed versions 2.3.32.3.3-tuxcare.12.3.3-tuxcare.2 | 2.3.3-tuxcare.3 |
dompurifyTuxCare:npm From an advisory covering 2 CVEs | 2.4.0-tuxcare.0 up to 2.4.0-tuxcare.8, plus listed versions 2.4.02.4.0-tuxcare.12.4.0-tuxcare.22.4.0-tuxcare.32.4.0-tuxcare.42.4.0-tuxcare.52.4.0-tuxcare.62.4.0-tuxcare.7 | 2.4.0-tuxcare.8 |
dompurifyTuxCare:npm From an advisory covering 5 CVEs | 3.0.6-tuxcare.0 up to 3.0.6-tuxcare.5, plus listed versions 3.0.63.0.6-tuxcare.13.0.6-tuxcare.23.0.6-tuxcare.33.0.6-tuxcare.4 | 3.0.6-tuxcare.5 |
dompurifyTuxCare:npm From an advisory covering 9 CVEs | 3.4.0-tuxcare.0 up to 3.4.0-tuxcare.1, plus listed versions 3.4.0 | 3.4.0-tuxcare.1 |
dompurifyTuxCare:npm From an advisory covering 10 CVEs | 3.0.5-tuxcare.0 up to 3.0.5-tuxcare.4, plus listed versions 3.0.53.0.5-tuxcare.13.0.5-tuxcare.23.0.5-tuxcare.3 | 3.0.5-tuxcare.4 |
dompurifyTuxCare:npm From an advisory covering 10 CVEs | 3.0.4-tuxcare.0 up to 3.0.4-tuxcare.4, plus listed versions 3.0.43.0.4-tuxcare.13.0.4-tuxcare.23.0.4-tuxcare.3 | 3.0.4-tuxcare.4 |
node-dompurifyDebian:12 | All versions, plus listed versions 2.4.1+dfsg+~2.4.0-12.4.1+dfsg+~2.4.0-22.4.1+dfsg+~2.4.0-2+deb12u13.0.9+dfsg+~3.0.5-13.1.6+dfsg+~3.0.5-1 Show 13 moreShow less3.1.7+dfsg+~3.0.5-13.1.7+dfsg+~3.0.5-23.2.5+dfsg-13.3.2+dfsg-13.3.3+dfsg-13.3.3+dfsg-23.4.1+dfsg-13.4.12+dfsg-13.4.13+dfsg-13.4.13+dfsg-23.4.16+dfsg-13.4.2+dfsg-13.4.5+dfsg-1 | None known |
node-dompurifyDebian:13 | All versions, plus listed versions 3.1.7+dfsg+~3.0.5-23.2.5+dfsg-13.3.2+dfsg-13.3.3+dfsg-13.3.3+dfsg-2 Show 7 moreShow less3.4.1+dfsg-13.4.12+dfsg-13.4.13+dfsg-13.4.13+dfsg-23.4.16+dfsg-13.4.2+dfsg-13.4.5+dfsg-1 | None known |
node-dompurifyDebian:14 | before 3.4.12+dfsg-1, plus listed versions 3.1.7+dfsg+~3.0.5-23.2.5+dfsg-13.3.2+dfsg-13.3.3+dfsg-13.3.3+dfsg-23.4.1+dfsg-13.4.2+dfsg-13.4.5+dfsg-1 | 3.4.12+dfsg-1 |
dompurifynpm | before 3.4.6 | 3.4.6 |
dompurifyRoot:npm | before 2.5.8-aikido.3 | 2.5.8-aikido.32.5.9-aikido.23.2.4-aikido.22.5.9-aikido.33.2.4-aikido.32.5.8-aikido.23.4.0-aikido.13.4.2-aikido.13.4.5-aikido.13.4.2-aikido.22.5.9-aikido.43.2.4-aikido.42.5.9-aikido.53.2.4-aikido.5 |
@rootio/dompurifyRoot:npm | before 2.5.8-root.io.3 | 2.5.8-root.io.32.5.9-root.io.23.2.4-root.io.22.5.9-root.io.33.2.4-root.io.32.5.8-root.io.23.4.0-root.io.13.4.2-root.io.13.4.5-root.io.13.4.2-root.io.22.5.9-root.io.43.2.4-root.io.42.5.9-root.io.53.2.4-root.io.5 |
handlebarsRoot:npm | before 3.0.7-aikido.3 | 3.0.7-aikido.33.0.3-aikido.23.0.8-aikido.13.0.8-aikido.2 |
@rootio/handlebarsRoot:npm | before 3.0.7-root.io.3 | 3.0.7-root.io.33.0.3-root.io.23.0.8-root.io.13.0.8-root.io.2 |
handlebarsRoot:npm | before 3.0.3-aikido.2 | 3.0.3-aikido.23.0.7-aikido.13.0.7-aikido.23.0.7-aikido.3 |
@rootio/handlebarsRoot:npm | before 3.0.3-root.io.2 | 3.0.3-root.io.23.0.7-root.io.13.0.7-root.io.23.0.7-root.io.3 |
dompurify.jsUbuntu:16.04:LTS | All versions, plus listed versions 0.7.3~dfsg1-10.7.3~dfsg1-2 | None known |
dompurify.jsUbuntu:18.04:LTS | All versions, plus listed versions 0.9.0~dfsg1-10.9.0~dfsg1-2 | None known |
node-dompurifyUbuntu:22.04:LTS | All versions, plus listed versions 2.3.0+dfsg-22.3.3+dfsg-1 | None known |
node-dompurifyUbuntu:24.04:LTS | All versions, plus listed versions 2.4.1+dfsg+~2.4.0-13.0.9+dfsg+~3.0.5-1 | None known |
node-dompurifyUbuntu:26.10 | All versions, plus listed versions 3.3.3+dfsg-13.4.2+dfsg-13.4.5+dfsg-13.4.12+dfsg-13.4.13+dfsg-13.4.13+dfsg-2 | None known |
node-dompurifyUbuntu:26.04:LTS | All versions, plus listed versions 3.1.7+dfsg+~3.0.5-23.3.3+dfsg-1 | None known |
What each source reports
CVE List Score used 6.1
DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
- Record
CVE-2026-49459- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79, CWE-693, CWE-1321
- Updated
- 2026-11-02
EUVDEUVD-2026-44450 6.1
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
- Record
EUVD-2026-44450- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2cf5-4w76-r9qv 7.3
Arbitrary Code Execution in handlebars
Versions of handlebars prior to 3.0.8 or 4.5.2 are vulnerable to Arbitrary Code Execution. The package's lookup helper fails to properly validate templates, allowing attackers to submit templates that execute arbitrary JavaScript in the system. It can be used to run arbitrary code in a server processing Handlebars templates or on a victim's browser (effectively serving as Cross-Site Scripting).
The following template can be used to demonstrate the vulnerability:
{{#with split as |a|}}
{{pop (push "alert('Vulnerable Handlebars JS');")}}
{{#with (concat (lookup join (slice 0 1)))}}
{{#each (slice 2 3)}}
{{#with (apply 0 a)}}
{{.}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}```
## Recommendation
Upgrade to version 3.0.8, 4.5.2 or later.
- Record
GHSA-2cf5-4w76-r9qv- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:L/I:H/A:L - Weakness
- CWE-94
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-q42p-pg8m-cqh6 7.3
Prototype Pollution in handlebars
Versions of handlebars prior to 4.0.14 are vulnerable to Prototype Pollution. Templates may alter an Objects' prototype, thus allowing an attacker to execute arbitrary code on the server.
Recommendation
For handlebars 4.1.x upgrade to 4.1.2 or later. For handlebars 4.0.x upgrade to 4.0.14 or later.
- Record
GHSA-q42p-pg8m-cqh6- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-471
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-r47g-fvhr-h676 6.1
DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
CWE: CWE-79 (XSS — Improper Neutralization of Input During Web Page Generation) via CWE-693 (Protection Mechanism Failure — silent no-op when _forceRemove is called on a parent-less node)
Summary
When DOMPurify.sanitize(root, { IN_PLACE: true }) is called and root is a <form> whose own attributes carry an event handler (onmouseover, onfocus, onclick, etc.), a single descendant element with a name= attribute matching any of the property names _isClobbered checks (nodeName, setAttribute, namespaceURI, insertBefore, hasChildNodes, childNodes) is sufficient to bypass attribute sanitization on the root. _forceRemove silently no-ops because the root has no parent; the iterator drives on to _sanitizeAttributes, which early-returns on clobbered nodes — and the event handler attribute is never inspected. The sanitized return is the same root, with the handler live.
This affects current main at 89da34e (the just-landed DOM-clobbering hardening fix at 89da34e addressed _sanitizeAttachedShadowRoots walk traversal, not the main _sanitizeElements / _sanitizeAttributes pipeline against the iterator-root node).
Affected
- DOMPurify ≤ 3.4.5, including
mainat89da34e03ec17868e561f87f3747a9371b61a9e7 - Any caller that does
DOMPurify.sanitize(node, { IN_PLACE: true })wherenodeis built from untrusted HTML (e.g., parsed viacreateElement('template').innerHTML = dirtythentemplate.content.firstElementChildhanded in)
Not affected:
- String-input
DOMPurify.sanitize(dirtyString)— the library builds the DOM itself inside_initDocument, the root is the cleanly-created document body, and clobber-named children of the body cannot shadowbodynamed properties (HTMLBodyElement does not carry[LegacyOverrideBuiltIns]) - IN_PLACE where the root is not an HTMLFormElement
- IN_PLACE where the attacker cannot place a clobber-named child inside the root
Vulnerability details
Code paths
[A] — _forceRemove at src/purify.ts:930-939:
const _forceRemove = function (node: Node): void {
arrayPush(DOMPurify.removed, { element: node });
try {
// eslint-disable-next-line unicorn/prefer-dom-node-remove
getParentNode(node).removeChild(node); // [A1] throws when getParentNode returns null
} catch (_) {
remove(node); // [A2] WebIDL Node.remove() — spec-defined no-op
} // when the node has no parent
};
When the iterator-root has no parent (the standard IN_PLACE case where the caller hands in a detached node), getParentNode(node) returns null, null.removeChild(node) throws, the catch falls to remove(node) — which per WebIDL is Element.prototype.remove.call(node), and per spec does nothing if the node has no parent. Nothing about _forceRemove's contract acknowledges this — the function appears to its callers as "the node is gone now," but the node is still in place.
[B] — _sanitizeAttributes at src/purify.ts:1490-1492:
const _sanitizeAttributes = function (currentNode: Element): void {
_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
const { attributes } = currentNode;
/* Check if we have attributes; if not we might have a text node */
if (!attributes || _isClobbered(currentNode)) {
return; // [B] silently skips ALL attribute checks
} // for clobbered nodes
...
};
The skip at [B] is deliberate — the intent is to avoid touching nodes the library has already decided to discard. The invariant the comment implies is "if _isClobbered, then _sanitizeElements already removed this node, so we will never reach _sanitizeAttributes on it." That invariant holds for every non-root node…
- Record
GHSA-r47g-fvhr-h676- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79, CWE-693, CWE-1321
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-g9r4-xpmj-mj65No score
Prototype Pollution in handlebars
Versions of handlebars prior to 3.0.8 or 4.5.3 are vulnerable to prototype pollution. It is possible to add or modify properties to the Object prototype through a malicious template. This may allow attackers to crash the application or execute Arbitrary Code in specific conditions.
Recommendation
Upgrade to version 3.0.8, 4.5.3 or later.
- Record
GHSA-g9r4-xpmj-mj65- Weakness
- CWE-1321
- Updated
- 2026-11-02
Show 37 moreShow less
GitHub AdvisoriesGHSA-q2c6-c6pm-g3ghNo score
Arbitrary Code Execution in handlebars
Versions of handlebars prior to 3.0.8 or 4.5.3 are vulnerable to Arbitrary Code Execution. The package's lookup helper fails to properly validate templates, allowing attackers to submit templates that execute arbitrary JavaScript in the system. It is due to an incomplete fix for a previous issue. This vulnerability can be used to run arbitrary code in a server processing Handlebars templates or on a victim's browser (effectively serving as Cross-Site Scripting).
Recommendation
Upgrade to version 3.0.8, 4.5.3 or later.
- Record
GHSA-q2c6-c6pm-g3gh- Updated
- 2026-11-02
NVD 6.1
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
- Record
CVE-2026-49459- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79, CWE-693, CWE-1321
- Updated
- 2026-11-02
OSV 6.1
DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
- Record
CVE-2026-49459- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-1321, CWE-693, CWE-79
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-49459 6.1
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
- Record
DEBIAN-CVE-2026-49459- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
OSVGHSA-2cf5-4w76-r9qv 7.3
Arbitrary Code Execution in handlebars
Versions of handlebars prior to 3.0.8 or 4.5.2 are vulnerable to Arbitrary Code Execution. The package's lookup helper fails to properly validate templates, allowing attackers to submit templates that execute arbitrary JavaScript in the system. It can be used to run arbitrary code in a server processing Handlebars templates or on a victim's browser (effectively serving as Cross-Site Scripting).
The following template can be used to demonstrate the vulnerability:
{{#with split as |a|}}
{{pop (push "alert('Vulnerable Handlebars JS');")}}
{{#with (concat (lookup join (slice 0 1)))}}
{{#each (slice 2 3)}}
{{#with (apply 0 a)}}
{{.}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}```
## Recommendation
Upgrade to version 3.0.8, 4.5.2 or later.
- Record
GHSA-2cf5-4w76-r9qv- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:L/I:H/A:L - Weakness
- CWE-94
- Updated
- 2026-11-02
OSVGHSA-q42p-pg8m-cqh6 7.3
Prototype Pollution in handlebars
Versions of handlebars prior to 4.0.14 are vulnerable to Prototype Pollution. Templates may alter an Objects' prototype, thus allowing an attacker to execute arbitrary code on the server.
Recommendation
For handlebars 4.1.x upgrade to 4.1.2 or later. For handlebars 4.0.x upgrade to 4.0.14 or later.
- Record
GHSA-q42p-pg8m-cqh6- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L - Weakness
- CWE-471
- Updated
- 2026-11-02
OSVGHSA-r47g-fvhr-h676 6.1
DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
CWE: CWE-79 (XSS — Improper Neutralization of Input During Web Page Generation) via CWE-693 (Protection Mechanism Failure — silent no-op when _forceRemove is called on a parent-less node)
Summary
When DOMPurify.sanitize(root, { IN_PLACE: true }) is called and root is a <form> whose own attributes carry an event handler (onmouseover, onfocus, onclick, etc.), a single descendant element with a name= attribute matching any of the property names _isClobbered checks (nodeName, setAttribute, namespaceURI, insertBefore, hasChildNodes, childNodes) is sufficient to bypass attribute sanitization on the root. _forceRemove silently no-ops because the root has no parent; the iterator drives on to _sanitizeAttributes, which early-returns on clobbered nodes — and the event handler attribute is never inspected. The sanitized return is the same root, with the handler live.
This affects current main at 89da34e (the just-landed DOM-clobbering hardening fix at 89da34e addressed _sanitizeAttachedShadowRoots walk traversal, not the main _sanitizeElements / _sanitizeAttributes pipeline against the iterator-root node).
Affected
- DOMPurify ≤ 3.4.5, including
mainat89da34e03ec17868e561f87f3747a9371b61a9e7 - Any caller that does
DOMPurify.sanitize(node, { IN_PLACE: true })wherenodeis built from untrusted HTML (e.g., parsed viacreateElement('template').innerHTML = dirtythentemplate.content.firstElementChildhanded in)
Not affected:
- String-input
DOMPurify.sanitize(dirtyString)— the library builds the DOM itself inside_initDocument, the root is the cleanly-created document body, and clobber-named children of the body cannot shadowbodynamed properties (HTMLBodyElement does not carry[LegacyOverrideBuiltIns]) - IN_PLACE where the root is not an HTMLFormElement
- IN_PLACE where the attacker cannot place a clobber-named child inside the root
Vulnerability details
Code paths
[A] — _forceRemove at src/purify.ts:930-939:
const _forceRemove = function (node: Node): void {
arrayPush(DOMPurify.removed, { element: node });
try {
// eslint-disable-next-line unicorn/prefer-dom-node-remove
getParentNode(node).removeChild(node); // [A1] throws when getParentNode returns null
} catch (_) {
remove(node); // [A2] WebIDL Node.remove() — spec-defined no-op
} // when the node has no parent
};
When the iterator-root has no parent (the standard IN_PLACE case where the caller hands in a detached node), getParentNode(node) returns null, null.removeChild(node) throws, the catch falls to remove(node) — which per WebIDL is Element.prototype.remove.call(node), and per spec does nothing if the node has no parent. Nothing about _forceRemove's contract acknowledges this — the function appears to its callers as "the node is gone now," but the node is still in place.
[B] — _sanitizeAttributes at src/purify.ts:1490-1492:
const _sanitizeAttributes = function (currentNode: Element): void {
_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
const { attributes } = currentNode;
/* Check if we have attributes; if not we might have a text node */
if (!attributes || _isClobbered(currentNode)) {
return; // [B] silently skips ALL attribute checks
} // for clobbered nodes
...
};
The skip at [B] is deliberate — the intent is to avoid touching nodes the library has already decided to discard. The invariant the comment implies is "if _isClobbered, then _sanitizeElements already removed this node, so we will never reach _sanitizeAttributes on it." That invariant holds for every non-root node…
- Record
GHSA-r47g-fvhr-h676- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-1321, CWE-693, CWE-79
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-49459 6.1
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.6, DOMPurify.sanitize(root, { IN_PLACE: true }) could preserve event-handler attributes on an attacker-controlled <form> root when a descendant name clobbered properties checked by _isClobbered, because _forceRemove no-opped on the parent-less root and _sanitizeAttributes returned early. This issue is fixed in version 3.4.6.
- Record
UBUNTU-CVE-2026-49459- CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
OSVCLSA-2026-1774743817No score
TuxCare security update for handlebars (1 CVE)
TuxCare rebuilt handlebars to address 1 CVE. Fixed in 1.3.0-tuxcare.1.
- Record
CLSA-2026-1774743817- Updated
- 2026-11-02
OSVCLSA-2026-1774743830No score
TuxCare security update for handlebars (3 CVEs)
TuxCare rebuilt handlebars to address 3 CVEs. Fixed in 1.0.12-tuxcare.2.
- Record
CLSA-2026-1774743830- Updated
- 2026-11-02
OSVCLSA-2026-1784164098No score
TuxCare security update for dompurify (5 CVEs)
TuxCare rebuilt dompurify to address 5 CVEs. Fixed in 3.1.6-tuxcare.4.
- Record
CLSA-2026-1784164098- Updated
- 2026-11-02
OSVCLSA-2026-1784682987No score
TuxCare security update for dompurify (8 CVEs)
TuxCare rebuilt dompurify to address 8 CVEs. Fixed in 3.2.3-tuxcare.2.
- Record
CLSA-2026-1784682987- Updated
- 2026-11-02
OSVCLSA-2026-1786636721No score
TuxCare security update for dompurify (14 CVEs)
TuxCare rebuilt dompurify to address 14 CVEs. Fixed in 2.4.7-tuxcare.1.
- Record
CLSA-2026-1786636721- Updated
- 2026-11-02
OSVCLSA-2026-1786731948No score
TuxCare security update for dompurify (34 CVEs)
TuxCare rebuilt dompurify to address 34 CVEs. Fixed in 3.0.3-tuxcare.1.
- Record
CLSA-2026-1786731948- Updated
- 2026-11-02
OSVCLSA-2026-1789139223No score
TuxCare security update for dompurify (3 CVEs)
TuxCare rebuilt dompurify to address 3 CVEs. Fixed in 3.2.7-tuxcare.2.
- Record
CLSA-2026-1789139223- Updated
- 2026-11-02
OSVCLSA-2026-1789152222No score
TuxCare security update for dompurify (11 CVEs)
TuxCare rebuilt dompurify to address 11 CVEs. Fixed in 2.3.0-tuxcare.5.
- Record
CLSA-2026-1789152222- Updated
- 2026-11-02
OSVCLSA-2026-1789154068No score
TuxCare security update for dompurify (12 CVEs)
TuxCare rebuilt dompurify to address 12 CVEs. Fixed in 3.0.3-tuxcare.5.
- Record
CLSA-2026-1789154068- Updated
- 2026-11-02
OSVCLSA-2026-1789154458No score
TuxCare security update for dompurify (9 CVEs)
TuxCare rebuilt dompurify to address 9 CVEs. Fixed in 2.4.7-tuxcare.5.
- Record
CLSA-2026-1789154458- Updated
- 2026-11-02
OSVCLSA-2026-1789155659No score
TuxCare security update for dompurify (12 CVEs)
TuxCare rebuilt dompurify to address 12 CVEs. Fixed in 2.4.3-tuxcare.8.
- Record
CLSA-2026-1789155659- Updated
- 2026-11-02
OSVCLSA-2026-1789155876No score
TuxCare security update for dompurify (8 CVEs)
TuxCare rebuilt dompurify to address 8 CVEs. Fixed in 2.5.8-tuxcare.7.
- Record
CLSA-2026-1789155876- Updated
- 2026-11-02
OSVCLSA-2026-1792150209No score
TuxCare security update for dompurify (9 CVEs)
TuxCare rebuilt dompurify to address 9 CVEs. Fixed in 3.4.5-tuxcare.2.
- Record
CLSA-2026-1792150209- Updated
- 2026-11-02
OSVCLSA-2026-1792156500No score
TuxCare security update for dompurify (6 CVEs)
TuxCare rebuilt dompurify to address 6 CVEs. Fixed in 2.0.8-tuxcare.2.
- Record
CLSA-2026-1792156500- Updated
- 2026-11-02
OSVCLSA-2026-1792159369No score
TuxCare security update for dompurify (5 CVEs)
TuxCare rebuilt dompurify to address 5 CVEs. Fixed in 3.3.3-tuxcare.2.
- Record
CLSA-2026-1792159369- Updated
- 2026-11-02
OSVCLSA-2026-1792161492No score
TuxCare security update for dompurify (10 CVEs)
TuxCare rebuilt dompurify to address 10 CVEs. Fixed in 3.2.6-tuxcare.2.
- Record
CLSA-2026-1792161492- Updated
- 2026-11-02
OSVCLSA-2026-1792424449No score
TuxCare security update for dompurify (12 CVEs)
TuxCare rebuilt dompurify to address 12 CVEs. Fixed in 2.3.3-tuxcare.3.
- Record
CLSA-2026-1792424449- Updated
- 2026-11-05
OSVCLSA-2026-1792791410No score
TuxCare security update for dompurify (2 CVEs)
TuxCare rebuilt dompurify to address 2 CVEs. Fixed in 2.4.0-tuxcare.8.
- Record
CLSA-2026-1792791410- Updated
- 2026-11-02
OSVCLSA-2026-1792929243No score
TuxCare security update for dompurify (7 CVEs)
TuxCare rebuilt dompurify to address 7 CVEs. Fixed in 3.0.6-tuxcare.5.
- Record
CLSA-2026-1792929243- Updated
- 2026-11-02
OSVCLSA-2026-1792933945No score
TuxCare security update for dompurify (12 CVEs)
TuxCare rebuilt dompurify to address 12 CVEs. Fixed in 3.4.0-tuxcare.1.
- Record
CLSA-2026-1792933945- Updated
- 2026-11-02
OSVCLSA-2026-1793101871No score
TuxCare security update for dompurify (11 CVEs)
TuxCare rebuilt dompurify to address 11 CVEs. Fixed in 3.0.5-tuxcare.4.
- Record
CLSA-2026-1793101871- Updated
- 2026-11-02
OSVCLSA-2026-1793102041No score
TuxCare security update for dompurify (11 CVEs)
TuxCare rebuilt dompurify to address 11 CVEs. Fixed in 3.0.4-tuxcare.4.
- Record
CLSA-2026-1793102041- Updated
- 2026-11-02
OSVGHSA-g9r4-xpmj-mj65No score
Prototype Pollution in handlebars
Versions of handlebars prior to 3.0.8 or 4.5.3 are vulnerable to prototype pollution. It is possible to add or modify properties to the Object prototype through a malicious template. This may allow attackers to crash the application or execute Arbitrary Code in specific conditions.
Recommendation
Upgrade to version 3.0.8, 4.5.3 or later.
- Record
GHSA-g9r4-xpmj-mj65- Weakness
- CWE-1321
- Updated
- 2026-11-02
OSVGHSA-q2c6-c6pm-g3ghNo score
Arbitrary Code Execution in handlebars
Versions of handlebars prior to 3.0.8 or 4.5.3 are vulnerable to Arbitrary Code Execution. The package's lookup helper fails to properly validate templates, allowing attackers to submit templates that execute arbitrary JavaScript in the system. It is due to an incomplete fix for a previous issue. This vulnerability can be used to run arbitrary code in a server processing Handlebars templates or on a victim's browser (effectively serving as Cross-Site Scripting).
Recommendation
Upgrade to version 3.0.8, 4.5.3 or later.
- Record
GHSA-q2c6-c6pm-g3gh- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-49459No score
CVE-2026-49459 in dompurify - Patched by Root
Root has patched CVE-2026-49459 in the dompurify package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-49459- Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-2cf5-4w76-r9qvNo score
GHSA-2cf5-4w76-r9qv in handlebars - Patched by Root
Root has patched GHSA-2cf5-4w76-r9qv in the handlebars package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-2cf5-4w76-r9qv- Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-g9r4-xpmj-mj65No score
GHSA-g9r4-xpmj-mj65 in handlebars - Patched by Root
Root has patched GHSA-g9r4-xpmj-mj65 in the handlebars package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-g9r4-xpmj-mj65- Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-q2c6-c6pm-g3ghNo score
GHSA-q2c6-c6pm-g3gh in handlebars - Patched by Root
Root has patched GHSA-q2c6-c6pm-g3gh in the handlebars package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-q2c6-c6pm-g3gh- Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-q42p-pg8m-cqh6No score
GHSA-q42p-pg8m-cqh6 in handlebars - Patched by Root
Root has patched GHSA-q42p-pg8m-cqh6 in the handlebars package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-q42p-pg8m-cqh6- Updated
- 2026-11-02
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, cwes, references | ||
| affected | ||
| facts | OSV | |
| affected | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
References
github.com/cure53/DOMPurify/security/advisories/GHSA-r47g-fvhr-h676
github.com/cure53/DOMPurify/commit/bb7739e5bccec7e1ab3dae3f3e42d02db3acaaae
github.com/cure53/DOMPurify/releases/tag/3.4.6
npmjs.com/advisories/1316
github.com/advisories/GHSA-2cf5-4w76-r9qv
npmjs.com/advisories/1325
Show 18 moreShow less
github.com/advisories/GHSA-g9r4-xpmj-mj65
npmjs.com/advisories/1324
github.com/advisories/GHSA-q2c6-c6pm-g3gh
github.com/handlebars-lang/handlebars.js/issues/1495
github.com/handlebars-lang/handlebars.js/commit/7372d4e9dffc9d70c09671aa28b9392a1577fd86
snyk.io/vuln/SNYK-JS-HANDLEBARS-173692
npmjs.com/advisories/755
github.com/handlebars-lang/handlebars.js/commit/0d6d8c335ad81bad1b672fc56b6a44f6aa472dac
github.com/handlebars-lang/handlebars.js/commit/85c8783b34fc6d36145d8b53885ad0b9e3c3f9c4
github.com/handlebars-lang/handlebars.js/commit/cd38583216dce3252831916323202749431c773e
github.com/advisories/GHSA-q42p-pg8m-cqh6
github.com/advisories/GHSA-r47g-fvhr-h676
github.com/CVEProject/cvelistV5/tree/main/cves/2026/49xxx/CVE-2026-49459.json
nvd.nist.gov/vuln/detail/CVE-2026-49459
security-tracker.debian.org/tracker/CVE-2026-49459
github.com/cure53/DOMPurify
ubuntu.com/security/CVE-2026-49459
cve.org/CVERecord?id=CVE-2026-49459
Left out here: the rest of 2 source descriptions. The JSON record has them.