CVE-2026-83615
xmldom: Quadratic-memory consumption
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
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: Quadratic-memory consumption
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
CVE-2026-83615- 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-770
- Updated
- 2026-11-02
EUVDEUVD-2026-69236
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
EUVD-2026-69236- 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-965w-775f-mr7g
8.7
xmldom: Quadratic-memory consumption
Summary
When an element declares a namespace prefix, xmldom copies the entire in-scope namespace map into a fresh object and keeps that copy on the element while it is open on the parse stack. A crafted document that nests N elements, each declaring one unique prefix, therefore drives the parser to hold on the order of N(N+1)/2 = O(N²) namespace-map entries at its peak, so a small, highly compressible input exhausts the heap. Parsing runs under default options on untrusted, network-delivered XML, so a sub-megabyte payload can OOM-crash the process before any application-level validation runs — an unauthenticated denial of service.
Details
appendElement performs the copy: _copy clones the current namespace map into a fresh object for
each prefix-declaring element, and the copy is retained on that element's parse-stack entry:
if (localNSMap == null) {
localNSMap = Object.create(null);
_copy(currentNSMap, (currentNSMap = Object.create(null))); // full copy of all ancestor prefixes
}
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
...
el.currentNSMap = currentNSMap; // retained while the element is open on the parse stack
https://github.com/xmldom/xmldom/blob/08a22d78e4bc50f12ce9f5090b8d96ee6031ac7b/lib/sax.js#L467-L540
The copies stack: the element at depth i copies a map of size ~i, and every ancestor stays live
on the parse stack until it closes, so at the deepest point Σi namespace entries are held at once.
That peak is transient — the completed DOM retains only O(N), one small namespace map per node — but
it is reached during parsing, which is what OOM-crashes the process.
Proof of Concept
A minimal document — N nested elements, each declaring one unique namespace prefix (no SAML wrapper needed):
const { DOMParser } = require('@xmldom/xmldom');
function build(n) {
let open = '', close = '';
for (let i = 0; i < n; i++) { open += `<a xmlns:p${i}="urn:${i}">`; close = '</a>' + close; }
return `<r>${open}${close}</r>`; // <r><a xmlns:p0="urn:0">...<a xmlns:p{n-1}="urn:{n-1}">...</a>...</r>
}
for (const n of [2000, 4000, 8000, 16000]) {
const src = build(n);
new DOMParser().parseFromString(src, 'text/xml'); // peak memory ~ O(n^2)
console.log(n, (src.length / 1024).toFixed(0) + ' KB in', (process.resourceUsage().maxRSS / 1024).toFixed(0) + ' MB peak RSS');
}
Measured on Node.js v24 (peak RSS ~quadruples per doubling of depth; absolute numbers vary by host):
| depth | input | peak RSS | | -----: | ------: | ------------------------------- | | 2,000 | 56 KB | 266 MB | | 4,000 | 115 KB | 622 MB | | 8,000 | 232 KB | 1.9 GB | | 16,000 | ~470 KB | OOM crash (default ~4 GB heap) |
About 470 KB of trivially-generated, highly-compressible input crashes a default Node.js process; larger depths scale as O(N²) into the tens of GB, crashing larger hosts (as first measured by the reporter with a SAML-shaped payload).
Impact
Unauthenticated denial of service against any service that parses attacker-influenced XML with xmldom under default options. A single sub-megabyte request drives multi-gigabyte peak memory and can OOM-crash the process before any application-level validation (e.g. schema checks or a SAML signature verification) runs. The payload is a plain namespace-nesting document and highly compressible, so it is effective over compressed transports (e.g. an HTTP-Redirect / DEFLATE binding, not only POST bindings).
Severity note
The CVSS 4.0 vector scores availability only (VC:N/VI:N/VA:H): the flaw neither discloses nor
alters data, it exhausts the heap. VA:H is justified because a single unauthenticated,
network-delivered request (AV:N/PR:N/UI:N) of trivial complexity (AC:L/AT:N) drives the parser
to multi-gigabyte peak memory and OOM-crashes the process before any application-level logic runs —
a full loss…
- Record
GHSA-965w-775f-mr7g- 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-770
- Updated
- 2026-11-02
NVD
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
CVE-2026-83615- 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 - Weakness
- CWE-770
- Updated
- 2026-11-02
OSV
8.7
xmldom: Quadratic-memory consumption
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
CVE-2026-83615- 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-770
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-83615
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
DEBIAN-CVE-2026-83615- 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 9 moreShow less
OSVGHSA-965w-775f-mr7g
8.7
xmldom: Quadratic-memory consumption
Summary
When an element declares a namespace prefix, xmldom copies the entire in-scope namespace map into a fresh object and keeps that copy on the element while it is open on the parse stack. A crafted document that nests N elements, each declaring one unique prefix, therefore drives the parser to hold on the order of N(N+1)/2 = O(N²) namespace-map entries at its peak, so a small, highly compressible input exhausts the heap. Parsing runs under default options on untrusted, network-delivered XML, so a sub-megabyte payload can OOM-crash the process before any application-level validation runs — an unauthenticated denial of service.
Details
appendElement performs the copy: _copy clones the current namespace map into a fresh object for
each prefix-declaring element, and the copy is retained on that element's parse-stack entry:
if (localNSMap == null) {
localNSMap = Object.create(null);
_copy(currentNSMap, (currentNSMap = Object.create(null))); // full copy of all ancestor prefixes
}
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
...
el.currentNSMap = currentNSMap; // retained while the element is open on the parse stack
https://github.com/xmldom/xmldom/blob/08a22d78e4bc50f12ce9f5090b8d96ee6031ac7b/lib/sax.js#L467-L540
The copies stack: the element at depth i copies a map of size ~i, and every ancestor stays live
on the parse stack until it closes, so at the deepest point Σi namespace entries are held at once.
That peak is transient — the completed DOM retains only O(N), one small namespace map per node — but
it is reached during parsing, which is what OOM-crashes the process.
Proof of Concept
A minimal document — N nested elements, each declaring one unique namespace prefix (no SAML wrapper needed):
const { DOMParser } = require('@xmldom/xmldom');
function build(n) {
let open = '', close = '';
for (let i = 0; i < n; i++) { open += `<a xmlns:p${i}="urn:${i}">`; close = '</a>' + close; }
return `<r>${open}${close}</r>`; // <r><a xmlns:p0="urn:0">...<a xmlns:p{n-1}="urn:{n-1}">...</a>...</r>
}
for (const n of [2000, 4000, 8000, 16000]) {
const src = build(n);
new DOMParser().parseFromString(src, 'text/xml'); // peak memory ~ O(n^2)
console.log(n, (src.length / 1024).toFixed(0) + ' KB in', (process.resourceUsage().maxRSS / 1024).toFixed(0) + ' MB peak RSS');
}
Measured on Node.js v24 (peak RSS ~quadruples per doubling of depth; absolute numbers vary by host):
| depth | input | peak RSS | | -----: | ------: | ------------------------------- | | 2,000 | 56 KB | 266 MB | | 4,000 | 115 KB | 622 MB | | 8,000 | 232 KB | 1.9 GB | | 16,000 | ~470 KB | OOM crash (default ~4 GB heap) |
About 470 KB of trivially-generated, highly-compressible input crashes a default Node.js process; larger depths scale as O(N²) into the tens of GB, crashing larger hosts (as first measured by the reporter with a SAML-shaped payload).
Impact
Unauthenticated denial of service against any service that parses attacker-influenced XML with xmldom under default options. A single sub-megabyte request drives multi-gigabyte peak memory and can OOM-crash the process before any application-level validation (e.g. schema checks or a SAML signature verification) runs. The payload is a plain namespace-nesting document and highly compressible, so it is effective over compressed transports (e.g. an HTTP-Redirect / DEFLATE binding, not only POST bindings).
Severity note
The CVSS 4.0 vector scores availability only (VC:N/VI:N/VA:H): the flaw neither discloses nor
alters data, it exhausts the heap. VA:H is justified because a single unauthenticated,
network-delivered request (AV:N/PR:N/UI:N) of trivial complexity (AC:L/AT:N) drives the parser
to multi-gigabyte peak memory and OOM-crashes the process before any application-level logic runs —
a full loss…
- Record
GHSA-965w-775f-mr7g- 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-770
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-83615
8.7
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
UBUNTU-CVE-2026-83615- 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
OSVAZL-99359 No score
CVE-2026-83615 affecting package python-tensorboard 2.16.2-6
xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. Prior to @xmldom/xmldom versions 0.8.15 and 0.9.12, and in xmldom versions 0.1.5 through 0.6.0, appendElement in lib/sax.js uses _copy to clone the complete currentNSMap for each nested element that declares a new namespace prefix. Keeping every ancestor map live on the parse stack creates quadratic peak namespace-map storage, so a small highly compressible XML document can exhaust the process heap before application validation. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
AZL-99359- Updated
- 2026-11-02
OSVCLSA-2026-1788980919 No score
TuxCare security update for xmldom (5 CVEs)
TuxCare rebuilt xmldom to address 5 CVEs. Fixed in 0.6.0-tuxcare.4.
- Record
CLSA-2026-1788980919- Updated
- 2026-11-02
OSVCLSA-2026-1790108624 No score
TuxCare security update for xmldom (5 CVEs)
TuxCare rebuilt xmldom to address 5 CVEs. Fixed in 0.1.31-tuxcare.5.
- Record
CLSA-2026-1790108624- 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-1790760268 No score
TuxCare security update for @xmldom/xmldom (4 CVEs)
TuxCare rebuilt @xmldom/xmldom to address 4 CVEs. Fixed in 0.9.10-tuxcare.2.
- Record
CLSA-2026-1790760268- Updated
- 2026-11-02
OSVCLSA-2026-1791192659 No score
TuxCare security update for @xmldom/xmldom (10 CVEs)
TuxCare rebuilt @xmldom/xmldom to address 10 CVEs. Fixed in 0.9.8-tuxcare.2.
- Record
CLSA-2026-1791192659- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-83615 No score
CVE-2026-83615 in @xmldom/xmldom - Patched by Root
Root has patched CVE-2026-83615 in the @xmldom/xmldom package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-83615- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@xmldom/xmldomnpm |
0.7.0 to 0.8.14 | 0.8.15 |
@xmldom/xmldomnpm |
0.9.0 to 0.9.11 | 0.9.12 |
xmldomnpm |
0.1.5 to 0.6.0 | None known |
python-tensorboardAzure Linux:3 |
through 2.16.2-6 | None known |
xmldomTuxCare:npm From an advisory covering 5 CVEs |
0.6.0-tuxcare.0 up to 0.6.0-tuxcare.4, plus listed versions 0.6.00.6.0-tuxcare.10.6.0-tuxcare.20.6.0-tuxcare.3 |
0.6.0-tuxcare.4 |
xmldomTuxCare:npm From an advisory covering 5 CVEs |
0.1.31-tuxcare.0 up to 0.1.31-tuxcare.5, plus listed versions 0.1.310.1.31-tuxcare.10.1.31-tuxcare.20.1.31-tuxcare.30.1.31-tuxcare.4 |
0.1.31-tuxcare.5 |
@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 4 CVEs |
0.9.10-tuxcare.0 up to 0.9.10-tuxcare.2, plus listed versions 0.9.100.9.10-tuxcare.1 |
0.9.10-tuxcare.2 |
@xmldom/xmldomTuxCare:npm From an advisory covering 8 CVEs |
0.9.8-tuxcare.0 up to 0.9.8-tuxcare.2, plus listed versions 0.9.80.9.8-tuxcare.1 |
0.9.8-tuxcare.2 |
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 |
Show 11 moreShow less
| Package | Affected | Fixed |
|---|---|---|
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.12-1, plus listed versions 0.9.10-10.9.10-20.9.11-10.9.6-10.9.8-10.9.8-20.9.9-1 |
0.9.12-1 |
@xmldom/xmldomnpm |
0.7.0 up to 0.8.15 | 0.8.15 |
@xmldom/xmldomnpm |
0.9.0 up to 0.9.12 | 0.9.12 |
@xmldom/xmldomRoot:npm |
before 0.8.14-aikido.1 | 0.8.14-aikido.10.9.11-aikido.10.8.13-aikido.10.7.13-aikido.50.8.13-aikido.2 |
@rootio/xmldom__xmldomRoot:npm |
before 0.8.14-root.io.1 | 0.8.14-root.io.10.9.11-root.io.10.8.13-root.io.10.7.13-root.io.50.8.13-root.io.2 |
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: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-83615 is a high vulnerability (CVSS 8.7) in @xmldom Xmldom, published September 1, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.59%, the 48th percentile. Fixed in @xmldom/xmldom 0.8.15.
References
github.com/xmldom/xmldom/security/advisories/GHSA-965w-775f-mr7g
github.com/xmldom/xmldom/pull/1071
github.com/xmldom/xmldom/pull/1072
github.com/xmldom/xmldom/commit/954370f58c046223faf95ba77efcbc8ce014409d
github.com/xmldom/xmldom/commit/dabffe884e864eeecb1f515c716f875e1bc47ec1
github.com/xmldom/xmldom/releases/tag/0.8.15
Show 8 moreShow less
github.com/xmldom/xmldom/releases/tag/0.9.12
nvd.nist.gov/vuln/detail/CVE-2026-83615
github.com/advisories/GHSA-965w-775f-mr7g
github.com/CVEProject/cvelistV5/tree/main/cves/2026/83xxx/CVE-2026-83615.json
security-tracker.debian.org/tracker/CVE-2026-83615
github.com/xmldom/xmldom
ubuntu.com/security/CVE-2026-83615
cve.org/CVERecord?id=CVE-2026-83615
Left out here: the rest of 2 source descriptions. The JSON record has them.