CVE-2026-41673 Overview
CVE-2026-41673 is an uncontrolled recursion vulnerability [CWE-674] in @xmldom/xmldom, a pure JavaScript W3C standard-based DOM Level 2 Core DOMParser and XMLSerializer module. Seven recursive traversal functions in lib/dom.js operate without depth limits. A sufficiently deeply nested DOM tree triggers a RangeError: Maximum call stack size exceeded, crashing the host application. The flaw affects @xmldom/xmldom versions before 0.9.10 and 0.8.13, plus the deprecated xmldom package version 0.6.0 and earlier. Maintainers patched the issue in @xmldom/xmldom 0.9.10 and 0.8.13.
Critical Impact
Remote attackers can crash any Node.js application that parses untrusted XML through xmldom by submitting a deeply nested document, causing denial of service without authentication or user interaction.
Affected Products
- @xmldom/xmldom versions prior to 0.9.10
- @xmldom/xmldom versions prior to 0.8.13
- xmldom version 0.6.0 and earlier (deprecated package)
Discovery Timeline
- 2026-05-07 - CVE-2026-41673 published to NVD
- 2026-05-07 - Last updated in NVD database
Technical Details for CVE-2026-41673
Vulnerability Analysis
The vulnerability lives in lib/dom.js, where seven DOM traversal routines walk the document tree using direct recursion. Each level of XML nesting consumes a JavaScript engine call frame. When the parsed DOM exceeds the V8 stack limit, the engine throws RangeError: Maximum call stack size exceeded and the Node.js process aborts the active operation.
Functions including importNode and serialization helpers traverse firstChild and nextSibling references recursively. None of them validate tree depth or switch to an iterative algorithm. Any caller that feeds attacker-controlled XML to DOMParser.parseFromString or to a serializer inherits the crash condition.
The attack reaches the network through any service that accepts XML input. Examples include SOAP endpoints, SAML assertion processors, RSS readers, SVG sanitizers, and configuration importers built on xmldom. Authentication and user interaction are not required.
Root Cause
The root cause is unbounded recursion in DOM walking logic. The code assumes well-formed inputs of reasonable depth and does not enforce a maximum nesting level. Because JavaScript lacks tail-call optimization in V8, every recursive call extends the engine stack until the hard limit is reached.
Attack Vector
An attacker submits an XML document containing thousands of nested elements such as <a><a><a>...</a></a></a>. When the application parses the payload and any traversal-based API runs over the resulting tree, the recursion exceeds the engine stack and the Node.js worker crashes.
// Patch excerpt: lib/dom.js — introduction of walkDOM
// Source: https://github.com/xmldom/xmldom/commit/2d6d6916ed8a4c223db1f6d7560ab4544c465b0f
/**
* Depth-first pre/post-order DOM tree walker.
*
* Visits every node in the subtree rooted at `node`. For each node:
*
* 1. Calls `callbacks.enter(node, context)` before descending into the node's
* children. The return value becomes the `context` passed to each child's
* `enter` call and to the matching `exit` call.
* 2. If `enter` returns `null` or `undefined`, the node's children are skipped;
* sibling traversal continues normally.
* 3. If `enter` returns `walkDOM.STOP`, the entire traversal is aborted
* immediately — no further `enter` or `exit` calls are made.
*
* Note: this implementation is recursive. It will be converted to an iterative
* form in a later step to eliminate stack-overflow risk on very deep trees.
*/
// Patch excerpt: lib/dom.js — importNode migrated to walkDOM
// Source: https://github.com/xmldom/xmldom/commit/291257493cb0eb6980eda83b162a9c4e6d7d2597
importNode: function (importedNode, deep) {
return importNode(this, importedNode, deep);
},
Detection Methods for CVE-2026-41673
Indicators of Compromise
- Repeated RangeError: Maximum call stack size exceeded entries in Node.js process logs originating from lib/dom.js frames.
- Unexpected worker restarts or process exits immediately after XML, SOAP, or SAML request handling.
- Inbound HTTP requests carrying XML payloads with abnormal nesting depth or repetitive opening tags.
Detection Strategies
- Inspect application dependency manifests for @xmldom/xmldom versions below 0.9.10 or 0.8.13, and any use of the deprecated xmldom package.
- Add a Web Application Firewall rule that flags XML bodies exceeding a configured element depth or size threshold.
- Correlate spikes in 5xx responses on XML-handling endpoints with stack-overflow stack traces in application telemetry.
Monitoring Recommendations
- Forward Node.js stderr and crash logs to a centralized log platform and alert on Maximum call stack size exceeded patterns.
- Track request size and parse-time metrics on every endpoint that calls DOMParser.parseFromString.
- Monitor container or process restart counts for services that perform XML, SAML, or SOAP processing.
How to Mitigate CVE-2026-41673
Immediate Actions Required
- Upgrade @xmldom/xmldom to version 0.9.10 or 0.8.13 on every Node.js service that parses XML.
- Replace the deprecated xmldom 0.6.0 package with the maintained @xmldom/xmldom fork at a patched version.
- Audit transitive dependencies with npm ls @xmldom/xmldom and npm ls xmldom to identify indirect exposure through libraries such as SAML or SOAP clients.
Patch Information
The maintainers fixed the issue by introducing a shared walkDOM traversal helper and migrating recursive functions to use it, with a stated plan to convert the helper to an iterative form. Fixed releases are @xmldom/xmldom 0.9.10 and @xmldom/xmldom 0.8.13. Full technical context is available in the GitHub Security Advisory GHSA-2v35-w6hq-6mfw.
Workarounds
- Reject XML payloads above a strict size limit at the reverse proxy or API gateway before they reach the Node.js parser.
- Pre-validate untrusted XML against a maximum nesting depth using a streaming SAX parser before invoking xmldom APIs.
- Run XML parsing inside isolated worker processes so a stack-overflow crash does not terminate the main service.
# Upgrade to a patched version of @xmldom/xmldom
npm install @xmldom/xmldom@0.9.10 --save
# Or, for the 0.8.x maintenance line
npm install @xmldom/xmldom@0.8.13 --save
# Verify no vulnerable versions remain in the dependency tree
npm ls @xmldom/xmldom
npm ls xmldom
# Audit project for known advisories
npm audit --production
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


