CVE-2026-83609 Overview
CVE-2026-83609 affects @xmldom/xmldom, a pure JavaScript W3C-standard DOMParser and XMLSerializer module. Versions from 0.9.0 up to and including 0.9.11 compile the anchored QName_exact validator with the multiline flag. As a result, ^ and $ match line boundaries instead of the complete name string. Callers of createElementNS, createAttributeNS, createDocumentType, and createAttribute accept a malformed XML name whose first line is valid but whose trailing lines inject markup once serialized. The issue is fixed in version 0.9.12 and is categorized under CWE-91: XML Injection.
Critical Impact
An attacker who controls name inputs passed to DOM creation APIs can inject arbitrary XML markup into serialized output, corrupting downstream parsers and integrity of XML-based data flows.
Affected Products
- @xmldom/xmldom version 0.9.0
- @xmldom/xmldom versions 0.9.1 through 0.9.11
- Node.js applications and libraries depending on vulnerable @xmldom/xmldom releases
Discovery Timeline
- 2026-09-01 - CVE-2026-83609 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-83609
Vulnerability Analysis
The defect resides in the shared reg() builder in lib/grammar.js. The builder compiles the anchored QName_exact regular expression with the multiline (m) flag. Under multiline semantics, ^ and $ match at every line terminator rather than only the start and end of the input. Name inputs whose first line satisfies the QName grammar pass validation even when subsequent lines contain arbitrary characters, including XML metacharacters. The ECMAScript line terminators that trigger the bypass are U+000A, U+000D, U+2028, and U+2029.
Once a crafted name reaches the serializer, whether through the default path or requireWellFormed: true, the trailing content is written verbatim. This produces output containing attacker-controlled tags, attributes, or text nodes that were never part of the DOM structure.
Root Cause
The root cause is the use of the multiline regular expression flag in an anchored full-string validator. Anchored validators must confirm that the entire input conforms to the grammar. The m flag reduces ^ and $ to per-line assertions, so validation succeeds against a partial match. Downstream code paths trust the validator and pass unvalidated multi-line data into createElementNS, createAttributeNS, createDocumentType, and createAttribute.
Attack Vector
The vulnerability is exploitable over the network wherever untrusted input flows into DOM name parameters. Typical scenarios include XML document generation pipelines, SOAP or SAML message construction, RSS/Atom feed builders, and API layers that mirror user-supplied identifiers into XML output. No privileges or user interaction are required.
// Patch: lib/grammar.js - drop the multiline flag from reg()
// Source: https://github.com/xmldom/xmldom/commit/7b2ec67e1750daadd0bb06c92e875e726544a362
return isStr ? part : part.source;
})
.join(''),
- UNICODE_SUPPORT ? 'mu' : 'm'
+ UNICODE_SUPPORT ? 'u' : ''
);
}
The fix removes the m flag so anchored patterns validate the whole string. A companion change in lib/sax.js reintroduces controlled multiline handling for end-tag names in HTML mode to preserve backward compatibility while making XML parses fatal on malformed names.
Detection Methods for CVE-2026-83609
Indicators of Compromise
- Serialized XML output containing unexpected tags, attributes, or text following a well-formed element name.
- Presence of U+000A, U+000D, U+2028, or U+2029 in strings passed to createElementNS, createAttributeNS, createDocumentType, or createAttribute.
- Downstream XML consumers logging parse errors immediately after processing content produced by a vulnerable service.
Detection Strategies
- Perform software composition analysis (SCA) across package.json and lockfiles to identify @xmldom/xmldom versions between 0.9.0 and 0.9.11.
- Add unit and integration tests that submit name inputs containing line terminators and assert that DOM creation APIs throw.
- Inspect application logs for XML serialization failures or schema validation errors originating from services using xmldom.
Monitoring Recommendations
- Instrument code paths that construct XML from user input to record raw name arguments before they reach xmldom APIs.
- Monitor WAF and API gateway telemetry for request bodies or parameters carrying embedded newline or paragraph separators in fields expected to be identifiers.
- Track dependency drift with automated alerts when @xmldom/xmldom versions below 0.9.12 reappear in builds.
How to Mitigate CVE-2026-83609
Immediate Actions Required
- Upgrade @xmldom/xmldom to version 0.9.12 or later across all application and transitive dependencies.
- Rebuild and redeploy Node.js services that ship xmldom inside container images or serverless bundles.
- Audit code that forwards user-controlled strings into DOM creation APIs and add explicit input validation.
Patch Information
The fix is delivered in @xmldom/xmldom 0.9.12. The corrective changes are described in GitHub Security Advisory GHSA-3px3-54cx-rmw9 and implemented in pull request 1071 and the associated commit.
Workarounds
- Reject any name input containing \n, \r, \\u2028, or \\u2029 before invoking createElementNS, createAttributeNS, createDocumentType, or createAttribute.
- Validate identifiers against a strict anchored QName pattern without the multiline flag prior to passing them to xmldom.
- Where feasible, avoid propagating unsanitized user data into XML element or attribute names.
# Upgrade to the patched release
npm install @xmldom/xmldom@0.9.12
# Verify no vulnerable versions remain in the dependency tree
npm ls @xmldom/xmldom
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

