Seven recursive traversals in lib/dom.js operate without a depth limit. A sufficiently deeply
nested DOM tree causes a RangeError: Maximum call stack size exceeded, crashing the application.
Reported operations:
Node.prototype.normalize() — reported by @praveen-kv (email 2026-04-05) and @KarimTantawey (GHSA-fwmp-8wwc-qhv6, via DOMParser.parseFromString())XMLSerializer.serializeToString() — reported by @Jvr2022 (GHSA-2v35-w6hq-6mfw) and @KarimTantawey (GHSA-j2hf-fqwf-rrjf)Additionally, discovered in research:
Element.getElementsByTagName() / getElementsByTagNameNS() / getElementsByClassName() / getElementById()Node.cloneNode(true)Document.importNode(node, true)node.textContent (getter)Node.isEqualNode(other)All seven share the same root cause: pure-JavaScript recursive tree traversal with no depth guard. A single deeply nested document (parsed successfully) triggers any or all of these operations.
lib/dom.js implements DOM tree traversals as depth-first recursive functions. Each level of
element nesting adds one JavaScript call frame. The JS engine's call stack is finite; once
exhausted, a RangeError: Maximum call stack size exceeded is thrown. This error may not be
caught reliably at stack-exhaustion depths because the catch handler itself requires stack
frames to execute — especially in async scenarios, where an uncaught RangeError inside a
callback or promise chain can crash the entire Node.js process.
Parsing a deeply nested document succeeds — the SAX parser in lib/sax.js is iterative.
The crash occurs during subsequent operations on the parsed DOM.
Node.prototype.normalize() — reported by @praveen-kvlib/dom.js:1296–1308 (main):
normalize: function () {
var child = this.firstChild;
while (child) {
var next =...
0.8.130.9.10Exploitability
AV:NAC:LAT:NPR:NUI:NVulnerable System
VC:NVI:NVA:HSubsequent System
SC:NSI:NSA:N8.7/CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N