CVE-2026-83607 Overview
CVE-2026-83607 is a name injection vulnerability in @xmldom/xmldom, a pure JavaScript W3C standard-based DOMParser and XMLSerializer module. The flaw resides in Document.createElement(tagName), which stores unvalidated element names. XMLSerializer.serializeToString() then emits those names verbatim, even when requireWellFormed: true is set. Attacker-controlled tag names can inject attributes, elements, or processing instructions into serialized XML or HTML output. When the serialized content is consumed by a browser, this results in cross-site scripting (XSS) [CWE-91]. The issue is fixed in @xmldom/xmldom versions 0.8.14 and 0.9.11. No fix is available for the legacy xmldom package (0.6.0 and earlier).
Critical Impact
Attacker-supplied element names bypass well-formedness checks and inject arbitrary markup into serialized output, enabling XSS in browser-consumed contexts.
Affected Products
- @xmldom/xmldom prior to version 0.8.14
- @xmldom/xmldom prior to version 0.9.11
- Legacy xmldom package version 0.6.0 and earlier (no fix available)
Discovery Timeline
- 2026-09-01 - CVE-2026-83607 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-83607
Vulnerability Analysis
The vulnerability is a classic XML injection issue [CWE-91] caused by missing validation on element and attribute qualified names. The Document.createElement(tagName) API accepts any string as a tag name and stores it directly on the node. During serialization, XMLSerializer.serializeToString() writes that string into the output stream without escaping or validating it against the XML QName production.
The requireWellFormed: true code path is documented to enforce W3C DOM Parsing §3.2.1.1 well-formedness checks. In the vulnerable versions, that path failed to validate element qualified names, prefixes, or synthesized xmlns:PREFIX declarations. Consumers that relied on requireWellFormed as a safety boundary received malformed and injected output instead.
Root Cause
The root cause is the absence of a QName regular-expression check at two points: creation-time in createElement and serialization-time in the requireWellFormed branch. Because tag names were treated as opaque strings, characters such as >, <, spaces, and quotes could terminate the emitting element and start new markup structures in the serialized document.
Attack Vector
An attacker who controls input passed to createElement() (for example, tag names derived from user input or untrusted data feeds) can craft a tag name that closes the current tag and injects new attributes, elements, or processing instructions. When the resulting XML or HTML is rendered by a browser, injected script content executes in the victim's origin.
// Security patch in lib/dom.js — imports the QName pattern used to validate names
// fix: reject invalid element and attribute names when requireWellFormed
var find = conventions.find;
var NAMESPACE = conventions.NAMESPACE;
var tagNamePattern = conventions.tagNamePattern;
/**
* A prerequisite for `[].filter`, to drop elements that are empty
*/
Source: GitHub Commit d8212e6
// Security patch in index.d.ts — documents the new InvalidStateError throws
// fix: reject invalid element and attribute names when requireWellFormed (#1043)
* @throws {DOMException}
* `InvalidStateError` when `requireWellFormed` is `true` and any of the following conditions
* hold:
* - an Element's qualified name (including any namespace prefix) is not a valid XML QName
* - an attribute's qualified name (including a synthesized `xmlns:` namespace declaration) is
* not a valid XML QName
* - CDATASection data contains `"]]>"`
* - Text data contains characters outside the XML Char production
* - a Comment node's data contains `--` anywhere or ends with `-`
Source: GitHub Commit cba1321
Detection Methods for CVE-2026-83607
Indicators of Compromise
- Serialized XML or HTML output containing tag names with characters outside the XML QName production, such as <, >, spaces, or quotes.
- Unexpected <script> blocks, event-handler attributes, or <?xml ...?> processing instructions in documents produced by XMLSerializer.serializeToString().
- Application logs showing createElement() calls with untrusted or user-controlled tag names.
Detection Strategies
- Perform Software Composition Analysis (SCA) across build artifacts and lockfiles to identify @xmldom/xmldom versions below 0.8.14 or 0.9.11, and any use of the deprecated xmldom package.
- Add code-review or static-analysis rules that flag calls to Document.createElement() where the argument is not a compile-time constant.
- Inspect XSS filters and Web Application Firewall (WAF) telemetry for payloads reaching endpoints that render server-generated XML or HTML.
Monitoring Recommendations
- Monitor npm dependency alerts and GitHub Dependabot advisories for GHSA-w2rr-34g9-rvrj.
- Log and alert on Content Security Policy (CSP) violation reports, which often surface injected inline scripts resulting from XML name injection.
- Track outbound serialized responses for structural anomalies using response-schema validation.
How to Mitigate CVE-2026-83607
Immediate Actions Required
- Upgrade @xmldom/xmldom to 0.8.14 (0.8.x branch) or 0.9.11 (0.9.x branch) immediately.
- Migrate off the legacy xmldom package, since no patched version is available for it.
- Audit all application code paths that pass untrusted input into Document.createElement() or attribute-creation APIs.
Patch Information
The fix is delivered in GitHub Release v0.8.14 and GitHub Release v0.9.11. The relevant changes land in GitHub Pull Request #1043 and GitHub Pull Request #1050, which validate element and attribute qualified names against the XML QName production and throw InvalidStateError when requireWellFormed is true. Full advisory details are in the GitHub Security Advisory GHSA-w2rr-34g9-rvrj.
Workarounds
- Validate tag names against the XML QName production (^[A-Za-z_][\w.\-]*(:[A-Za-z_][\w.\-]*)?$) before passing them to createElement().
- Never pass user-controlled strings directly as element or attribute names; use a fixed allow-list of known-safe names.
- Apply output encoding and a strict Content Security Policy on any browser-consumed HTML or XML produced by the serializer.
# Configuration example: upgrade to a patched release
npm install @xmldom/xmldom@0.9.11
# or, for the 0.8.x line
npm install @xmldom/xmldom@0.8.14
# Verify the installed version
npm ls @xmldom/xmldom
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

