Every CVE Search/ Get API key

CVE-2026-83613

xmldom: Quadratic-time attribute deduplication

8.7 HighFix available

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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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

0.60%Up 0.3 points since Sep 2, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.7

xmldom: Quadratic-time attribute deduplication

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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-83613
CVSS 4.0
8.7 HighCVSS: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-407
Updated
2026-11-02
EUVDEUVD-2026-69231 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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-69231
CVSS 4.0
8.7 HighCVSS: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-8344-3jmq-59r6 8.7

xmldom: Quadratic-time attribute deduplication

Summary

xmldom builds the attribute collection of every parsed element by inserting attributes one at a time into a DOM NamedNodeMap. Each insertion first performs a linear scan of all already-inserted attributes to enforce the DOM uniqueness rule (no two attributes with the same qualified name / namespace+local-name). Parsing an element that carries M distinct attributes therefore costs 1 + 2 + … + M = O(M²) comparisons.

Because the trigger is simply "one element with many attributes", the attack payload is a fully well-formed XML document. No malformed markup, no error recovery, and no non-default parser options are involved — parsing completes silently with zero warning/error/fatalError events. An attacker who can submit a modest, highly compressible document (a single element with tens of thousands of attributes, ~340 KB uncompressed) can consume seconds of single-threaded CPU per request, enabling an unauthenticated denial of service.

This is distinct from the known quadratic-memory namespace-map issue: it burns CPU and it does not require any namespace declarations or nesting.

Details

The DOM content handler adds each attribute of a starting element by calling el.setAttributeNode(attr) in a loop:

// DOMHandler.startElement
for (var i = 0; i < len; i++) {
	var namespaceURI = attrs.getURI(i);
	var value = attrs.getValue(i);
	var qName = attrs.getQName(i);
	var attr = doc.createAttributeNS(namespaceURI, qName);
	attr.value = attr.nodeValue = value;
	el.setAttributeNode(attr);          // O(existing attrs) each — see below
}

https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom-parser.js#L370-L387

setAttributeNode delegates to NamedNodeMap.setNamedItem, which calls getNamedItemNS to look for an existing attribute with the same namespace URI and local name before appending:

setNamedItem: function (attr) {
	var el = attr.ownerElement;
	if (el && el !== this._ownerElement) {
		throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
	}
	var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);  // linear scan
	if (oldAttr === attr) {
		return attr;
	}
	_addNamedNode(this._ownerElement, this, attr, oldAttr);
	return oldAttr;
},

https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L612-L623

getNamedItemNS walks the whole list on every call:

getNamedItemNS: function (namespaceURI, localName) {
	if (!namespaceURI) {
		namespaceURI = null;
	}
	var i = 0;
	while (i < this.length) {
		var node = this[i];
		if (node.localName === localName && node.namespaceURI === namespaceURI) {
			return node;
		}
		i++;
	}
	return null;
},

https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L702-L715

For the i-th attribute the scan visits i-1 entries, so inserting M distinct attributes performs Θ(M²) comparisons. There is no hash index or set keyed by name; the map is a plain array-backed structure.

The same structure exists on 0.8.x. There setNamedItem dedups via getNamedItem(attr.nodeName) instead of getNamedItemNS, but that method is likewise a full linear scan, so the complexity is identical:

The linear-scan NamedNodeMap predates the @xmldom/xmldom fork and is present unchanged in the unscoped xmldom package back to its earliest published release. In [email protected], parsing already inserts each attribute one at a time (DOMHandler.startElement loops calling setAttributeNS → setAttributeNode → NamedNodeMap.setNamedItem), and setNamedItem dedups by calling getNamedItemNS, which is a full linear `while…

Record
GHSA-8344-3jmq-59r6
CVSS 4.0
8.7 HighCVSS: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-407
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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-83613
CVSS 4.0
8.7 HighCVSS: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-407
Updated
2026-11-02
OSV 8.7

xmldom: Quadratic-time attribute deduplication

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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-83613
CVSS 4.0
8.7 HighCVSS: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-407
Updated
2026-11-02
OSVDEBIAN-CVE-2026-83613 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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-83613
CVSS 4.0
8.7 HighCVSS: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-8344-3jmq-59r6 8.7

xmldom: Quadratic-time attribute deduplication

Summary

xmldom builds the attribute collection of every parsed element by inserting attributes one at a time into a DOM NamedNodeMap. Each insertion first performs a linear scan of all already-inserted attributes to enforce the DOM uniqueness rule (no two attributes with the same qualified name / namespace+local-name). Parsing an element that carries M distinct attributes therefore costs 1 + 2 + … + M = O(M²) comparisons.

Because the trigger is simply "one element with many attributes", the attack payload is a fully well-formed XML document. No malformed markup, no error recovery, and no non-default parser options are involved — parsing completes silently with zero warning/error/fatalError events. An attacker who can submit a modest, highly compressible document (a single element with tens of thousands of attributes, ~340 KB uncompressed) can consume seconds of single-threaded CPU per request, enabling an unauthenticated denial of service.

This is distinct from the known quadratic-memory namespace-map issue: it burns CPU and it does not require any namespace declarations or nesting.

Details

The DOM content handler adds each attribute of a starting element by calling el.setAttributeNode(attr) in a loop:

// DOMHandler.startElement
for (var i = 0; i < len; i++) {
	var namespaceURI = attrs.getURI(i);
	var value = attrs.getValue(i);
	var qName = attrs.getQName(i);
	var attr = doc.createAttributeNS(namespaceURI, qName);
	attr.value = attr.nodeValue = value;
	el.setAttributeNode(attr);          // O(existing attrs) each — see below
}

https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom-parser.js#L370-L387

setAttributeNode delegates to NamedNodeMap.setNamedItem, which calls getNamedItemNS to look for an existing attribute with the same namespace URI and local name before appending:

setNamedItem: function (attr) {
	var el = attr.ownerElement;
	if (el && el !== this._ownerElement) {
		throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
	}
	var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);  // linear scan
	if (oldAttr === attr) {
		return attr;
	}
	_addNamedNode(this._ownerElement, this, attr, oldAttr);
	return oldAttr;
},

https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L612-L623

getNamedItemNS walks the whole list on every call:

getNamedItemNS: function (namespaceURI, localName) {
	if (!namespaceURI) {
		namespaceURI = null;
	}
	var i = 0;
	while (i < this.length) {
		var node = this[i];
		if (node.localName === localName && node.namespaceURI === namespaceURI) {
			return node;
		}
		i++;
	}
	return null;
},

https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L702-L715

For the i-th attribute the scan visits i-1 entries, so inserting M distinct attributes performs Θ(M²) comparisons. There is no hash index or set keyed by name; the map is a plain array-backed structure.

The same structure exists on 0.8.x. There setNamedItem dedups via getNamedItem(attr.nodeName) instead of getNamedItemNS, but that method is likewise a full linear scan, so the complexity is identical:

The linear-scan NamedNodeMap predates the @xmldom/xmldom fork and is present unchanged in the unscoped xmldom package back to its earliest published release. In [email protected], parsing already inserts each attribute one at a time (DOMHandler.startElement loops calling setAttributeNS → setAttributeNode → NamedNodeMap.setNamedItem), and setNamedItem dedups by calling getNamedItemNS, which is a full linear `while…

Record
GHSA-8344-3jmq-59r6
CVSS 4.0
8.7 HighCVSS: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-407
Updated
2026-11-02
OSVUBUNTU-CVE-2026-83613 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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-83613
CVSS 4.0
8.7 HighCVSS: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-99353 No score

CVE-2026-83613 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 version 0.6.0 and earlier, DOMHandler.startElement in lib/dom-parser.js inserts every parsed attribute through setAttributeNode, while NamedNodeMap.setNamedItem in lib/dom.js calls the linear getNamedItem or getNamedItemNS lookup for each insertion. A well-formed element with many distinct attributes therefore requires quadratic comparisons during DOMParser.parseFromString() and can stall a Node.js event loop 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-99353
Updated
2026-11-02
OSVCLSA-2026-1790608669 No score

TuxCare security update for @xmldom/xmldom (9 CVEs)

TuxCare rebuilt @xmldom/xmldom to address 9 CVEs. Fixed in 0.9.10-tuxcare.1.

Record
CLSA-2026-1790608669
Updated
2026-11-02
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
OSVCLSA-2026-1793867503 No score

TuxCare security update for xmldom (2 CVEs)

TuxCare rebuilt xmldom to address 2 CVEs. Fixed in 0.1.31-tuxcare.8.

Record
CLSA-2026-1793867503
Updated
2026-11-05
OSVCLSA-2026-1793867506 No score

TuxCare security update for xmldom (2 CVEs)

TuxCare rebuilt xmldom to address 2 CVEs. Fixed in 0.6.0-tuxcare.8.

Record
CLSA-2026-1793867506
Updated
2026-11-05
OSVROOT-APP-NPM-CVE-2026-83613 No score

CVE-2026-83613 in @xmldom/xmldom - Patched by Root

Root has patched CVE-2026-83613 in the @xmldom/xmldom package for Root:npm. Multiple fixed versions available.

Record
ROOT-APP-NPM-CVE-2026-83613
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@xmldom/xmldom
npm
0.7.0 to 0.8.14
0.8.15
@xmldom/xmldom
npm
0.9.0 to 0.9.11
0.9.12
xmldom
npm
through 0.6.0 None known
python-tensorboard
Azure Linux:3
through 2.16.2-6 None known
@xmldom/xmldom
TuxCare:npm
From an advisory covering 9 CVEs
0.9.10-tuxcare.0 up to 0.9.10-tuxcare.1, plus listed versions
0.9.10
0.9.10-tuxcare.1
@xmldom/xmldom
TuxCare: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/xmldom
TuxCare: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
xmldom
TuxCare:npm
From an advisory covering 2 CVEs
0.1.31-tuxcare.0 up to 0.1.31-tuxcare.8, plus listed versions
0.1.310.1.31-tuxcare.10.1.31-tuxcare.20.1.31-tuxcare.30.1.31-tuxcare.40.1.31-tuxcare.50.1.31-tuxcare.60.1.31-tuxcare.7
0.1.31-tuxcare.8
xmldom
TuxCare:npm
From an advisory covering 2 CVEs
0.6.0-tuxcare.0 up to 0.6.0-tuxcare.8, plus listed versions
0.6.00.6.0-tuxcare.10.6.0-tuxcare.20.6.0-tuxcare.30.6.0-tuxcare.40.6.0-tuxcare.50.6.0-tuxcare.60.6.0-tuxcare.7
0.6.0-tuxcare.8
node-xmldom
Debian: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 less
0.9.5-10.9.6-10.9.8-10.9.8-20.9.9-1
None known
Show 11 moreShow less
Affected packages
PackageAffectedFixed
node-xmldom
Debian: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-xmldom
Debian: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/xmldom
npm
0.7.0 up to 0.8.15
0.8.15
@xmldom/xmldom
npm
0.9.0 up to 0.9.12
0.9.12
@xmldom/xmldom
Root: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__xmldom
Root: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-xmldom
Ubuntu:20.04:LTS
All versions, plus listed versions
0.1.27+ds-10.1.27+ds-1+deb10u2build0.20.04.1
None known
node-xmldom
Ubuntu: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-xmldom
Ubuntu:24.04:LTS
All versions, plus listed versions
0.8.6-1
None known
node-xmldom
Ubuntu:26.10
All versions, plus listed versions
0.9.8-20.9.10-20.9.11-1
None known
node-xmldom
Ubuntu:26.04:LTS
All versions, plus listed versions
0.9.6-10.9.8-10.9.8-2
None known

History

History
RecordedChangedSources
affected
affected, aliases, factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-83613 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.60%, the 49th percentile. Fixed in @xmldom/xmldom 0.8.15.

References

Show 9 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open