CVE-2026-83611 Overview
CVE-2026-83611 is a parser differential vulnerability in @xmldom/xmldom, a pure JavaScript W3C standard-based DOMParser and XMLSerializer module. The flaw affects @xmldom/xmldom versions prior to 0.8.15 and 0.9.12, and all xmldom versions up to and including 0.6.0. The DOMParser.parseFromString() method silently accepts malformed end tags such as </a\njunk>, closes the element, and discards trailing content. On the 0.9.x branch, the lib/sax.js end-tag validator inherits the multiline flag from reg(), which allows anchored XML ETag production to match only the first line. This parser differential can bypass parse-before-trust well-formedness gates in security-sensitive pipelines.
Critical Impact
Attackers can craft XML payloads that pass one parser's well-formedness validation while being interpreted differently downstream, enabling security control bypass in signature validation and trust decision workflows.
Affected Products
- @xmldom/xmldom versions prior to 0.8.15
- @xmldom/xmldom versions 0.9.x prior to 0.9.12
- xmldom version 0.6.0 and earlier (no fix available)
Discovery Timeline
- 2026-09-01 - CVE-2026-83611 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-83611
Vulnerability Analysis
The vulnerability, classified under CWE-1286 (Improper Validation of Syntactic Correctness of Input), stems from how xmldom handles end-tag validation. The XML ETag production is defined as '</' Name S? '>', meaning only optional whitespace may follow the Name. A well-formed parser must reject any end tag containing non-whitespace residue after the tag name.
Instead, xmldom silently accepts inputs like </a\nbogus> or </a bogus>, discards the residue, and closes the element as if the tag were valid. This creates a parser differential: strict downstream consumers reject the input while xmldom accepts it, or vice versa. The discarded content is not injected into the resulting DOM, but the well-formedness contract is broken.
Root Cause
On the 0.9.x branch, the root cause is the multiline (m) regex flag inherited from the reg() helper in lib/grammar.js. The anchored regex ^...$ used to validate the end-tag name allows the ^ and $ anchors to match at line breaks when m is set. A tag name followed by \n and additional content satisfies the anchored production on the first line, while trailing lines receive no validation. On 0.8.x, a related recovery path also fails to flag whitespace-separated residue.
Attack Vector
An attacker supplies a crafted XML document to any application that uses xmldom to parse untrusted input as a well-formedness gate. The malformed end tag passes validation on the xmldom side while a strict parser at the trust boundary either rejects it or interprets it differently. This is exploitable in signature verification, XML-based authentication tokens, and any workflow that assumes syntactic equivalence between parsers.
// Security patch in lib/sax.js - reports not-well-formed end-tag trailing content
tagName = tagName.replace(/[\s<].*/,'');
errorHandler.error("end tag name: "+tagName+' maybe not complete');
end = tagStart+1+tagName.length;
// NEW: detect and report whitespace + trailing residue after Name
} else if(/[ \t\n\r]/.test(tagName) && tagNamePattern.test(tagName.split(/[ \t\n\r]/)[0])){
errorHandler.error('end tag name is followed by whitespace and trailing content: "'+tagName+'"');
}
// Source: https://github.com/xmldom/xmldom/commit/4430189660b0d380ee9c9ee7550a1358688e8828
The companion patch in lib/grammar.js removes the multiline flag from the reg() helper, preventing the anchor bypass:
// Before: UNICODE_SUPPORT ? 'mu' : 'm'
// After: UNICODE_SUPPORT ? 'u' : ''
// Source: https://github.com/xmldom/xmldom/commit/7b2ec67e1750daadd0bb06c92e875e726544a362
Detection Methods for CVE-2026-83611
Indicators of Compromise
- XML payloads containing end tags with trailing content after a line break, such as </tagname\ntrailing> or </tagname bogus>.
- Applications logging end tag name is followed by whitespace and trailing content or end tag name is followed by a line break and trailing content after patching.
- Discrepancies in XML validation results between xmldom and strict parsers such as libxml2 on the same input.
Detection Strategies
- Inventory Node.js projects and package lockfiles for @xmldom/xmldom versions below 0.8.15 or 0.9.12, and any use of unmaintained xmldom.
- Enable errorHandler on 0.8.x and onError on 0.9.x to surface recoverable well-formedness errors that were previously silent.
- Cross-validate parsed XML with a second strict parser at trust boundaries and alert on divergence.
Monitoring Recommendations
- Log all recoverable parser errors reported by xmldom after upgrading; treat repeated malformed end-tag errors as suspicious.
- Instrument SAML, WS-Security, and XML-DSig verification paths for input samples that trigger end-tag warnings.
- Track outbound package advisories via GitHub Dependabot and the GHSA-6h8r-xr42-gp59 advisory.
How to Mitigate CVE-2026-83611
Immediate Actions Required
- Upgrade @xmldom/xmldom to 0.8.15 or 0.9.12 in all Node.js applications and rebuild dependent artifacts.
- Migrate away from the abandoned xmldom package to the maintained @xmldom/xmldom fork; no fix will ship for xmldom.
- Audit XML processing paths that rely on parse-before-trust patterns and enforce strict errorHandler escalation to fatal.
Patch Information
The fix is delivered in two commits: 4430189 reports trailing content after end-tag names as recoverable errors, and 7b2ec67 drops the multiline flag from the grammar reg() helper. Releases are available at v0.8.15 and v0.9.12. See also PR #1071 and PR #1072.
Workarounds
- Wrap DOMParser instances with a custom errorHandler or onError that escalates all warnings and recoverable errors to fatal exceptions.
- Pre-validate untrusted XML with a strict parser such as libxml2 before passing it to xmldom.
- Reject XML inputs where end-tag content contains embedded whitespace or newlines before invoking parseFromString().
# Upgrade to a patched version
npm install @xmldom/xmldom@^0.9.12
# or for the 0.8.x line
npm install @xmldom/xmldom@^0.8.15
# Verify 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.

