CVE-2026-83608
xmldom: DocType `name` Injection Bypasses requireWellFormed
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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.7
xmldom: DocType `name` Injection Bypasses requireWellFormed
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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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-83608- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-91
- Updated
- 2026-11-02
EUVDEUVD-2026-69219
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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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-69219- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-27p8-2357-5qqv
8.7
xmldom: DocType `name` Injection Bypasses requireWellFormed
Summary
The @xmldom/xmldom serializer emits DocumentType.name verbatim into the
<!DOCTYPE …> declaration with no well-formedness guard. GHSA-f6ww-3ggp-fr8h
(CVE-2026-41674) hardened the serializer's requireWellFormed path for a
DocumentType's sibling fields — publicId, systemId, and internalSubset —
but it did not add any check for name. A > (or whitespace) in the name
terminates the doctype declaration early, letting the remaining characters
become sibling markup in the serialized output.
Because requireWellFormed: true — the recommended mitigation for the prior
xmldom injection CVEs — performs no validation on the DocType name, this is a
bypass of that control, in the same family as the open element-name
(GHSA-w2rr-34g9-rvrj) and attribute-name (GHSA-4w3w-2rp5-g8jm) name-injection advisories.
Details
The serializer's DOCUMENT_TYPE_NODE case runs the requireWellFormed block
only against publicId, systemId, and internalSubset, then pushes
n.name directly into the buffer between the <!DOCTYPE prefix and the
closing >:
- 0.9.x (v0.9.10,
bb7a085): serializer DocType case,lib/dom.js#L3256-L3283— therequireWellFormedblock (#L3259-L3269) validatespublicId/systemId/internalSubsetbut notname, which is emitted verbatim at #L3270. - 0.8.x (v0.8.13,
e5c1480): serializer DocType case,lib/dom.js#L1914-L1946— same structure;nameis emitted verbatim at #L1928. - unscoped
xmldom(v0.6.0,c80a161):lib/dom.js#L1105emitsnode.nameverbatim; this line predatesrequireWellFormed, so there is no well-formedness path at all.
Enabling write paths
DocumentType.name is a plain, writable own-property, so the enabling vector
differs by line:
- 0.9.x —
createDocumentType()validates the name viavalidateQualifiedName(lib/dom.js#L925-L936, validation at #L926), so the deliverable vector is a direct property write (dt.name = 'html><script>…') to the unguarded own-property. - 0.8.x —
createDocumentType()does not validate the name (lib/dom.js#L456-L464), so the malicious name is reachable directly throughcreateDocumentType()as well as via direct property write. - unscoped
xmldom(<= 0.6.0) —createDocumentType()does not validate the name (lib/dom.js#L286), same as 0.8.x.
This is the same structural root cause the sibling name-injection advisories
share: the serializer's requireWellFormed path validates content delimiters
but no name field, and every name-like field is a plain writable property, so
mutation / direct property-write bypasses any creation-time check.
Root Cause
- The serializer's
requireWellFormedDocType block checkspublicId,systemId, andinternalSubset(the fields hardened by GHSA-f6ww-3ggp-fr8h) but has no check forname. DocumentType.nameis a plain writable own-property; on 0.8.x and the unscoped package…
- Record
GHSA-27p8-2357-5qqv- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-91
- 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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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-83608- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/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-91
- Updated
- 2026-11-02
OSV
8.7
xmldom: DocType `name` Injection Bypasses requireWellFormed
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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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-83608- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-91
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-83608
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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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-83608- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/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-27p8-2357-5qqv
8.7
xmldom: DocType `name` Injection Bypasses requireWellFormed
Summary
The @xmldom/xmldom serializer emits DocumentType.name verbatim into the
<!DOCTYPE …> declaration with no well-formedness guard. GHSA-f6ww-3ggp-fr8h
(CVE-2026-41674) hardened the serializer's requireWellFormed path for a
DocumentType's sibling fields — publicId, systemId, and internalSubset —
but it did not add any check for name. A > (or whitespace) in the name
terminates the doctype declaration early, letting the remaining characters
become sibling markup in the serialized output.
Because requireWellFormed: true — the recommended mitigation for the prior
xmldom injection CVEs — performs no validation on the DocType name, this is a
bypass of that control, in the same family as the open element-name
(GHSA-w2rr-34g9-rvrj) and attribute-name (GHSA-4w3w-2rp5-g8jm) name-injection advisories.
Details
The serializer's DOCUMENT_TYPE_NODE case runs the requireWellFormed block
only against publicId, systemId, and internalSubset, then pushes
n.name directly into the buffer between the <!DOCTYPE prefix and the
closing >:
- 0.9.x (v0.9.10,
bb7a085): serializer DocType case,lib/dom.js#L3256-L3283— therequireWellFormedblock (#L3259-L3269) validatespublicId/systemId/internalSubsetbut notname, which is emitted verbatim at #L3270. - 0.8.x (v0.8.13,
e5c1480): serializer DocType case,lib/dom.js#L1914-L1946— same structure;nameis emitted verbatim at #L1928. - unscoped
xmldom(v0.6.0,c80a161):lib/dom.js#L1105emitsnode.nameverbatim; this line predatesrequireWellFormed, so there is no well-formedness path at all.
Enabling write paths
DocumentType.name is a plain, writable own-property, so the enabling vector
differs by line:
- 0.9.x —
createDocumentType()validates the name viavalidateQualifiedName(lib/dom.js#L925-L936, validation at #L926), so the deliverable vector is a direct property write (dt.name = 'html><script>…') to the unguarded own-property. - 0.8.x —
createDocumentType()does not validate the name (lib/dom.js#L456-L464), so the malicious name is reachable directly throughcreateDocumentType()as well as via direct property write. - unscoped
xmldom(<= 0.6.0) —createDocumentType()does not validate the name (lib/dom.js#L286), same as 0.8.x.
This is the same structural root cause the sibling name-injection advisories
share: the serializer's requireWellFormed path validates content delimiters
but no name field, and every name-like field is a plain writable property, so
mutation / direct property-write bypasses any creation-time check.
Root Cause
- The serializer's
requireWellFormedDocType block checkspublicId,systemId, andinternalSubset(the fields hardened by GHSA-f6ww-3ggp-fr8h) but has no check forname. DocumentType.nameis a plain writable own-property; on 0.8.x and the unscoped package…
- Record
GHSA-27p8-2357-5qqv- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-91
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-83608
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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. 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-83608- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
OSVAZL-99345 No score
CVE-2026-83608 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, the DOCUMENT_TYPE_NODE branch in lib/dom.js validates publicId, systemId, and internalSubset under requireWellFormed: true but emits DocumentType.name verbatim. A name containing > or whitespace can terminate the <!DOCTYPE ...> declaration and inject sibling markup; the value can be supplied through createDocumentType() on the 0.8.x and unscoped lines or through a direct DocumentType.name property write on every affected line. The default path and legacy creation-time behavior remain permissive, while the vulnerable strict path fails to enforce an XML Name. This issue is fixed in @xmldom/xmldom versions 0.8.15 and 0.9.12; no fixed version is available for xmldom.
- Record
AZL-99345- Updated
- 2026-11-02
OSVCLSA-2026-1789030963 No score
TuxCare security update for xmldom (1 CVE)
TuxCare rebuilt xmldom to address 1 CVE. Fixed in 0.6.0-tuxcare.5.
- Record
CLSA-2026-1789030963- Updated
- 2026-11-05
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-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-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-83608 No score
CVE-2026-83608 in @xmldom/xmldom - Patched by Root
Root has patched CVE-2026-83608 in the @xmldom/xmldom package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-83608- 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 |
through 0.6.0 | None known |
python-tensorboardAzure Linux:3 |
through 2.16.2-6 | None known |
xmldomTuxCare:npm |
0.6.0-tuxcare.0 up to 0.6.0-tuxcare.5, plus listed versions 0.6.00.6.0-tuxcare.10.6.0-tuxcare.20.6.0-tuxcare.30.6.0-tuxcare.4 |
0.6.0-tuxcare.5 |
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 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/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 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-83608 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.61%, the 49th percentile. Fixed in @xmldom/xmldom 0.8.15.
References
github.com/xmldom/xmldom/security/advisories/GHSA-27p8-2357-5qqv
github.com/xmldom/xmldom/pull/1071
github.com/xmldom/xmldom/pull/1072
github.com/xmldom/xmldom/commit/57aec90ac57b4408ae7c5d1746bf2a693b5ed90e
github.com/xmldom/xmldom/commit/85f12eb4d14b44de33216cfb72b50af4d24e9fdd
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-83608
github.com/advisories/GHSA-27p8-2357-5qqv
github.com/CVEProject/cvelistV5/tree/main/cves/2026/83xxx/CVE-2026-83608.json
security-tracker.debian.org/tracker/CVE-2026-83608
github.com/xmldom/xmldom
ubuntu.com/security/CVE-2026-83608
cve.org/CVERecord?id=CVE-2026-83608
Left out here: the rest of 2 source descriptions. The JSON record has them.