CVE-2026-41673
xmldom: Denial of service via uncontrolled recursion in XML serialization
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
xmldom: Denial of service via uncontrolled recursion in XML serialization
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
- Record
CVE-2026-41673- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-674, CWE-776
- Updated
- 2026-11-02
EUVDEUVD-2026-28288
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
- Record
EUVD-2026-28288- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2v35-w6hq-6mfw
8.7
xmldom: Uncontrolled recursion in XML serialization leads to DoS
Summary
Seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply
nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application.
Reported operations:
Node.prototype.normalize()— reported by @praveen-kv (email 2026-04-05) and @KarimTantawey (GHSA-fwmp-8wwc-qhv6, viaDOMParser.parseFromString())XMLSerializer.serializeToString()— reported by @Jvr2022 (GHSA-2v35-w6hq-6mfw) and @KarimTantawey (GHSA-j2hf-fqwf-rrjf)
Additionally, discovered in research:
Element.getElementsByTagName()/getElementsByTagNameNS()/getElementsByClassName()/getElementById()Node.cloneNode(true)Document.importNode(node, true)node.textContent(getter)Node.isEqualNode(other)
All seven share the same root cause: pure-JavaScript recursive tree traversal with no depth guard. A single deeply nested document (parsed successfully) triggers any or all of these operations.
Details
Root cause
lib/dom.js implements DOM tree traversals as depth-first recursive functions. Each level of
element nesting adds one JavaScript call frame. The JS engine's call stack is finite; once
exhausted, a RangeError: Maximum call stack size exceeded is thrown. This error may not be
caught reliably at stack-exhaustion depths because the catch handler itself requires stack
frames to execute — especially in async scenarios, where an uncaught RangeError inside a
callback or promise chain can crash the entire Node.js process.
Parsing a deeply nested document succeeds — the SAX parser in lib/sax.js is iterative.
The crash occurs during subsequent operations on the parsed DOM.
Node.prototype.normalize() — reported by @praveen-kv
lib/dom.js:1296–1308 (main):
normalize: function () {
var child = this.firstChild;
while (child) {
var next = child.nextSibling;
if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) {
this.removeChild(next);
child.appendData(next.data);
} else {
child.normalize(); // recursive call — no depth guard
child = next;
}
}
},
Crash threshold (Node.js 18, default stack): ~10,000 levels.
XMLSerializer.serializeToString() — reported by @Jvr2022
lib/dom.js:2790–2974 (main):
The internal serializeToString worker recurses into child nodes at four call sites, each
passing a visibleNamespaces.slice() copy. The per-frame allocation causes earlier stack
exhaustion than normalize().
Crash threshold (Node.js 18, default stack): ~5,000 levels.
Additional recursive entry points
All five crash at ~10,000 levels on Node.js 18.
| Function | Definition | Public API entry point(s) | Crash depth (Node.js 18) |
|-----------------------------|----------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|--------------------------|
| _visitNode | lib/dom.js:1529 | getElementsByTagName(), getElementsByTagNameNS(), getElementsByClassName(), getElementById() | ~10,000 levels |
| cloneNode (module fn) | lib/dom.js:3037 | Node.prototype.cloneNode(true) …
- Record
GHSA-2v35-w6hq-6mfw- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-674
- Updated
- 2026-11-02
NVD
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
- Record
CVE-2026-41673- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-674, CWE-776
- Updated
- 2026-11-02
OSV
8.7
xmldom: Denial of service via uncontrolled recursion in XML serialization
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
- Record
CVE-2026-41673- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-674
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-41673
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
- Record
DEBIAN-CVE-2026-41673- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Updated
- 2026-11-02
Show 6 moreShow less
OSVGHSA-2v35-w6hq-6mfw
8.7
xmldom: Uncontrolled recursion in XML serialization leads to DoS
Summary
Seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply
nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application.
Reported operations:
Node.prototype.normalize()— reported by @praveen-kv (email 2026-04-05) and @KarimTantawey (GHSA-fwmp-8wwc-qhv6, viaDOMParser.parseFromString())XMLSerializer.serializeToString()— reported by @Jvr2022 (GHSA-2v35-w6hq-6mfw) and @KarimTantawey (GHSA-j2hf-fqwf-rrjf)
Additionally, discovered in research:
Element.getElementsByTagName()/getElementsByTagNameNS()/getElementsByClassName()/getElementById()Node.cloneNode(true)Document.importNode(node, true)node.textContent(getter)Node.isEqualNode(other)
All seven share the same root cause: pure-JavaScript recursive tree traversal with no depth guard. A single deeply nested document (parsed successfully) triggers any or all of these operations.
Details
Root cause
lib/dom.js implements DOM tree traversals as depth-first recursive functions. Each level of
element nesting adds one JavaScript call frame. The JS engine's call stack is finite; once
exhausted, a RangeError: Maximum call stack size exceeded is thrown. This error may not be
caught reliably at stack-exhaustion depths because the catch handler itself requires stack
frames to execute — especially in async scenarios, where an uncaught RangeError inside a
callback or promise chain can crash the entire Node.js process.
Parsing a deeply nested document succeeds — the SAX parser in lib/sax.js is iterative.
The crash occurs during subsequent operations on the parsed DOM.
Node.prototype.normalize() — reported by @praveen-kv
lib/dom.js:1296–1308 (main):
normalize: function () {
var child = this.firstChild;
while (child) {
var next = child.nextSibling;
if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) {
this.removeChild(next);
child.appendData(next.data);
} else {
child.normalize(); // recursive call — no depth guard
child = next;
}
}
},
Crash threshold (Node.js 18, default stack): ~10,000 levels.
XMLSerializer.serializeToString() — reported by @Jvr2022
lib/dom.js:2790–2974 (main):
The internal serializeToString worker recurses into child nodes at four call sites, each
passing a visibleNamespaces.slice() copy. The per-frame allocation causes earlier stack
exhaustion than normalize().
Crash threshold (Node.js 18, default stack): ~5,000 levels.
Additional recursive entry points
All five crash at ~10,000 levels on Node.js 18.
| Function | Definition | Public API entry point(s) | Crash depth (Node.js 18) |
|-----------------------------|----------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|--------------------------|
| _visitNode | lib/dom.js:1529 | getElementsByTagName(), getElementsByTagNameNS(), getElementsByClassName(), getElementById() | ~10,000 levels |
| cloneNode (module fn) | lib/dom.js:3037 | Node.prototype.cloneNode(true) …
- Record
GHSA-2v35-w6hq-6mfw- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-674
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-41673
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.
- Record
UBUNTU-CVE-2026-41673- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVCLSA-2026-1778114662 No score
TuxCare security update for xmldom (3 CVEs)
TuxCare rebuilt xmldom to address 3 CVEs. Fixed in 0.6.0-tuxcare.2.
- Record
CLSA-2026-1778114662- Updated
- 2026-11-05
OSVCLSA-2026-1790755546 No score
TuxCare security update for @xmldom/xmldom (14 CVEs)
TuxCare rebuilt @xmldom/xmldom to address 14 CVEs. Fixed in 0.7.13-tuxcare.1.
- Record
CLSA-2026-1790755546- Updated
- 2026-11-02
OSVCLSA-2026-1791028067 No score
TuxCare security update for @xmldom/xmldom (3 CVEs)
TuxCare rebuilt @xmldom/xmldom to address 3 CVEs. Fixed in 0.9.8-tuxcare.1.
- Record
CLSA-2026-1791028067- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-41673 No score
CVE-2026-41673 in @xmldom/xmldom - Patched by Root
Root has patched CVE-2026-41673 in the @xmldom/xmldom package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-41673- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@xmldom/xmldomnpm |
before 0.8.13 | 0.8.13 |
@xmldom/xmldomnpm |
0.9.0 up to 0.9.10 | 0.9.10 |
xmldomnpm |
through 0.6.0 | None known |
xmldomTuxCare:npm From an advisory covering 3 CVEs |
0.6.0-tuxcare.0 up to 0.6.0-tuxcare.2, plus listed versions 0.6.00.6.0-tuxcare.1 |
0.6.0-tuxcare.2 |
@xmldom/xmldomTuxCare:npm From an advisory covering 14 CVEs |
0.7.13-tuxcare.0 up to 0.7.13-tuxcare.1, plus listed versions 0.7.13 |
0.7.13-tuxcare.1 |
@xmldom/xmldomTuxCare:npm From an advisory covering 3 CVEs |
0.9.8-tuxcare.0 up to 0.9.8-tuxcare.1, plus listed versions 0.9.8 |
0.9.8-tuxcare.1 |
node-xmldomDebian:12 |
All versions, plus listed versions 0.8.6-10.9.10-10.9.10-20.9.11-10.9.12-1 Show 5 moreShow less0.9.5-10.9.6-10.9.8-10.9.8-20.9.9-1 |
None known |
node-xmldomDebian:13 |
All versions, plus listed versions 0.9.10-10.9.10-20.9.11-10.9.12-10.9.6-10.9.8-10.9.8-20.9.9-1 |
None known |
node-xmldomDebian:14 |
before 0.9.10-1, plus listed versions 0.9.6-10.9.8-10.9.8-20.9.9-1 |
0.9.10-1 |
@xmldom/xmldomRoot:npm |
before 0.7.13-aikido.2 | 0.7.13-aikido.20.7.13-aikido.30.9.8-aikido.20.8.11-aikido.20.7.13-aikido.50.8.13-aikido.20.7.13-aikido.40.8.13-aikido.1 |
Show 7 moreShow less
| Package | Affected | Fixed |
|---|---|---|
@rootio/xmldom__xmldomRoot:npm |
before 0.9.8-root.io.1 | 0.9.8-root.io.10.8.11-root.io.10.7.13-root.io.10.7.13-root.io.20.7.13-root.io.30.9.8-root.io.20.8.11-root.io.20.7.13-root.io.50.8.13-root.io.20.7.13-root.io.40.8.13-root.io.1 |
node-xmldomUbuntu:20.04:LTS |
All versions, plus listed versions 0.1.27+ds-10.1.27+ds-1+deb10u2build0.20.04.1 |
None known |
node-xmldomUbuntu:22.04:LTS |
All versions, plus listed versions 0.5.0-10.7.3-10.7.5-10.7.5-1ubuntu0.22.04.1 |
None known |
node-xmldomUbuntu:24.04:LTS |
All versions, plus listed versions 0.8.6-1 |
None known |
node-xmldomUbuntu:25.10 |
All versions, plus listed versions 0.9.6-1 |
None known |
node-xmldomUbuntu:26.10 |
All versions, plus listed versions 0.9.8-20.9.10-20.9.11-1 |
None known |
node-xmldomUbuntu:26.04:LTS |
All versions, plus listed versions 0.9.6-10.9.8-10.9.8-2 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-41673 is a high vulnerability (CVSS 8.7) in Xmldom, published April 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.64%, the 51st percentile. Fixed in @xmldom/xmldom 0.8.13.
References
github.com/xmldom/xmldom/security/advisories/GHSA-2v35-w6hq-6mfw
github.com/xmldom/xmldom/commit/17678a2a73ecbd1a2da90f3d47dc23da9cef81aa
github.com/xmldom/xmldom/commit/291257493cb0eb6980eda83b162a9c4e6d7d2597
github.com/xmldom/xmldom/commit/2d6d6916ed8a4c223db1f6d7560ab4544c465b0f
github.com/xmldom/xmldom/commit/430357c7b6333108856e917bf2367afe5ceb6f8a
github.com/xmldom/xmldom/commit/4845ef109221df0890825de2822fbe77afba3afe
Show 19 moreShow less
github.com/xmldom/xmldom/commit/8834218c85ac2a4d757b9587c9028e67c2f7b6c3
github.com/xmldom/xmldom/commit/8b7cfd1491314abdc347261921d7334ff15f7112
github.com/xmldom/xmldom/commit/b0620383abc1df067f3ce1014c43ae1bc1161eeb
github.com/xmldom/xmldom/commit/e6edcab6bef5bcdba0b220bb35442aa72f452b84
github.com/xmldom/xmldom/releases/tag/0.8.13
github.com/xmldom/xmldom/releases/tag/0.9.10
access.redhat.com/security/cve/CVE-2026-41673
bugzilla.redhat.com/show_bug.cgi?id=2467630
security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-41673.json
access.redhat.com/errata/RHSA-2026:26234
access.redhat.com/errata/RHSA-2026:60520
nvd.nist.gov/vuln/detail/CVE-2026-41673
github.com/advisories/GHSA-2v35-w6hq-6mfw
github.com/CVEProject/cvelistV5/tree/main/cves/2026/41xxx/CVE-2026-41673.json
security-tracker.debian.org/tracker/CVE-2026-41673
github.com/xmldom/xmldom
ubuntu.com/security/CVE-2026-41673
cve.org/CVERecord?id=CVE-2026-41673
github.com/xmldom/xmldom/commit/5cdb515630fa8ca25f840b3ff1420c045545af1b
Left out here: the rest of 2 source descriptions. The JSON record has them.