xmldom

Ecosystem: npm

Downloads: 5.82 Mln

Vulnerabilities from the last (months)
  • 2CriticalAffects 2 versions
  • 12HighAffects 12 versions
  • 0MediumAffects 0 versions
  • 4ModerateAffects 4 versions
  • 0LowAffects 0 versions
Severity distribution (all time)
18vulnerabilities
  • Critical2 (11.1%)
  • High12 (66.7%)
  • Medium0 (0.0%)
  • Moderate4 (22.2%)
  • Low0 (0.0%)

Monthly breakdown

  • Critical
  • High
  • Medium
  • Moderate
  • Low
  • 9 vulnerabilities
    • Critical: 0
    • High: 7
    • Medium: 0
    • Moderate: 2
    • Low: 0
  • 5 vulnerabilities
    • Critical: 0
    • High: 5
    • Medium: 0
    • Moderate: 0
    • Low: 0
  • 1 vulnerabilities
    • Critical: 1
    • High: 0
    • Medium: 0
    • Moderate: 0
    • Low: 0
  • 1 vulnerabilities
    • Critical: 1
    • High: 0
    • Medium: 0
    • Moderate: 0
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0

Vulnerabilities (18)

Known vulnerabilities affecting xmldom, based on data from OSV.

Vulnerabilities affecting xmldom
IDSeveritySummaryAffected versionsPublishedSource
GHSA-27p8-2357-5qqvHighxmldom: DocType `name` Injection Bypasses requireWellFormed## Summary The `@xmldom/xmldom` serializer emits `DocumentType.name` verbatim into the `<!DOCTYPE …>` declaration with no well-formedness guard. GHSA-f6ww-3ggp-fr8h (CVE-2026-41674) hardened the serializer's `requireWellFormed` path for a DocumentType's sibling fields — `publicId`, `systemId`, and `internalSubset` — but it did **not** add any check for `name`. A `>` (or whitespace) in the name terminates the doctype declaration early, letting the remaining characters become sibling markup in the serialized output. Because `requireWellFormed: true` — the recommended mitigation for the prior x
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-4w3w-2rp5-g8jmHighxmldom: Attribute name injection via setAttribute() bypasses requireWellFormed## Summary `Element.setAttribute()` in `@xmldom/xmldom` bypasses attribute name validation by calling the private `_createAttribute(name)` method, which performs no validation. The public `createAttribute()` method correctly validates names against an anchored `QName` pattern, but `setAttribute()` never uses it. The serializer escapes attribute *values* but trusts attribute *names*, allowing an attacker to inject additional attributes (including event handlers) into serialized output. The `requireWellFormed: true` option did not catch this. ## Details `Element.setAttribute(name, value)` cre
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-6h8r-xr42-gp59Moderatexmldom: Parser silently accepts a not-well-formed end tag whose name is followed by a line break and trailing content## Summary xmldom's parser silently accepts a **not-well-formed end tag** whose valid name is followed by trailing content — e.g. `</a⏎junk>`. The element is closed, the trailing content is discarded, and no error is reported, even though the XML end-tag production allows only optional whitespace after the name and both Chromium and Firefox reject such input as `application/xml`. An application that relies on xmldom to reject not-well-formed input therefore receives a false "valid" result for a document the specification and browsers consider malformed. ## Details Across every affected vers
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-8344-3jmq-59r6Highxmldom: Quadratic-time attribute deduplication## Summary xmldom builds the attribute collection of every parsed element by inserting attributes one at a time into a DOM `NamedNodeMap`. Each insertion first performs a **linear scan of all already-inserted attributes** to enforce the DOM uniqueness rule (no two attributes with the same qualified name / namespace+local-name). Parsing an element that carries `M` distinct attributes therefore costs `1 + 2 + … + M = O(M²)` comparisons. Because the trigger is simply "one element with many attributes", the attack payload is a **fully well-formed XML document**. No malformed markup, no error rec
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-93r5-fhx6-vmg9Highxmldom: Quadratic-time parsing via the malformed-input recovery path — `parseElementStartPart` re-scan and `normalize()` adjacent-text merge## Summary `xmldom`'s malformed-input **error-recovery path** has two quadratic-time (O(n²)) behaviors that a single crafted input triggers together, so a tiny, highly compressible document (tens of KB) stalls the Node.js event loop for multiple seconds. It is reachable from `DOMParser.parseFromString` under **default options** — i.e. from unauthenticated, network-delivered XML — making this an unauthenticated denial of service. One of the two behaviors, the `normalize()` adjacent-text merge, is **additionally reachable programmatically** — via a plain `normalize()` call on a DOM built with a
  • >= 0.3.0, <= 0.6.0
GitHub (opens in a new tab)
GHSA-965w-775f-mr7gHighxmldom: Quadratic-memory consumption## Summary When an element declares a namespace prefix, xmldom copies the entire in-scope namespace map into a fresh object and keeps that copy on the element while it is open on the parse stack. A crafted document that nests N elements, each declaring one unique prefix, therefore drives the parser to hold on the order of N(N+1)/2 = **O(N²) namespace-map entries at its peak**, so a small, highly compressible input exhausts the heap. Parsing runs under default options on untrusted, network-delivered XML, so a sub-megabyte payload can OOM-crash the process before any application-level validatio
  • >= 0.1.5, <= 0.6.0
GitHub (opens in a new tab)
GHSA-c7q8-3ch8-vqpvHighxmldom: Processing Instruction Target Injection Bypasses requireWellFormed## Summary `Document.createProcessingInstruction()` in `@xmldom/xmldom` performs no validation on the `target` parameter. The `requireWellFormed: true` serializer option validates only for `:` in the target and a case-insensitive `xml` prefix, but does not check for `>` characters. A `>` in the target breaks the processing instruction boundary (`<?...?>`), allowing injection of arbitrary content into the serialized XML output. ## Details `Document.createProcessingInstruction(target, data)` at `lib/dom.js` around line 2413 accepts any string as the `target` parameter and stores it on the PI
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-w2rr-34g9-rvrjHighxmldom: Element name injection via createElement() bypasses requireWellFormed## Summary `Document.createElement()` in `@xmldom/xmldom` accepts arbitrary strings as the `tagName` parameter with zero validation. The serializer emits the tag name verbatim into XML/HTML output. Critically, the `requireWellFormed: true` serializer option — the recommended mitigation from CVE-2026-41672, CVE-2026-41674, and CVE-2026-34601 — did NOT catch this, making it a bypass of the existing security controls. An attacker who controls the element name string can inject arbitrary attributes (including event handlers) into the serialized output, leading to XSS when the output is consumed
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-6gmq-8vp8-gcm6Moderatexmldom: XML fragment injection via invalid EntityReference.nodeName during requireWellFormed serialization## Summary An `EntityReference` node can be created with an invalid, attacker-controlled name through `Document.createEntityReference(name)`. When this node is serialized directly with: ```js serializer.serializeToString(ref, { requireWellFormed: true }) ``` the invalid `nodeName` is emitted into the serialized XML fragment without validation or escaping. This can produce real XML markup in the serialized output. In the proof of concept below, the serialized fragment contains `<injected/>`, and reparsing the fragment creates a real `injected` element. --- ## Details The issue appears to
  • <= 0.6.0
GitHub (opens in a new tab)
GHSA-2v35-w6hq-6mfwHighxmldom: Uncontrolled recursion in XML serialization leads to DoS## Summary 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()` / `getElement
  • <= 0.6.0
GitHub (opens in a new tab)
  • GHSA-27p8-2357-5qqvHigh
    xmldom: DocType `name` Injection Bypasses requireWellFormed
    • <= 0.6.0

    ## Summary The `@xmldom/xmldom` serializer emits `DocumentType.name` verbatim into the `<!DOCTYPE …>` declaration with no well-formedness guard. GHSA-f6ww-3ggp-fr8h (CVE-2026-41674) hardened the serializer's `requireWellFormed` path for a DocumentType's sibling fields — `publicId`, `systemId`, and `internalSubset` — but it did **not** add any check for `name`. A `>` (or whitespace) in the name terminates the doctype declaration early, letting the remaining characters become sibling markup in the serialized output. Because `requireWellFormed: true` — the recommended mitigation for the prior x

    CVE: CVE-2026-83608

  • GHSA-4w3w-2rp5-g8jmHigh
    xmldom: Attribute name injection via setAttribute() bypasses requireWellFormed
    • <= 0.6.0

    ## Summary `Element.setAttribute()` in `@xmldom/xmldom` bypasses attribute name validation by calling the private `_createAttribute(name)` method, which performs no validation. The public `createAttribute()` method correctly validates names against an anchored `QName` pattern, but `setAttribute()` never uses it. The serializer escapes attribute *values* but trusts attribute *names*, allowing an attacker to inject additional attributes (including event handlers) into serialized output. The `requireWellFormed: true` option did not catch this. ## Details `Element.setAttribute(name, value)` cre

    CVE: CVE-2026-83605

  • GHSA-6h8r-xr42-gp59Moderate
    xmldom: Parser silently accepts a not-well-formed end tag whose name is followed by a line break and trailing content
    • <= 0.6.0

    ## Summary xmldom's parser silently accepts a **not-well-formed end tag** whose valid name is followed by trailing content — e.g. `</a⏎junk>`. The element is closed, the trailing content is discarded, and no error is reported, even though the XML end-tag production allows only optional whitespace after the name and both Chromium and Firefox reject such input as `application/xml`. An application that relies on xmldom to reject not-well-formed input therefore receives a false "valid" result for a document the specification and browsers consider malformed. ## Details Across every affected vers

    CVE: CVE-2026-83611

  • GHSA-8344-3jmq-59r6High
    xmldom: Quadratic-time attribute deduplication
    • <= 0.6.0

    ## Summary xmldom builds the attribute collection of every parsed element by inserting attributes one at a time into a DOM `NamedNodeMap`. Each insertion first performs a **linear scan of all already-inserted attributes** to enforce the DOM uniqueness rule (no two attributes with the same qualified name / namespace+local-name). Parsing an element that carries `M` distinct attributes therefore costs `1 + 2 + … + M = O(M²)` comparisons. Because the trigger is simply "one element with many attributes", the attack payload is a **fully well-formed XML document**. No malformed markup, no error rec

    CVE: CVE-2026-83613

  • GHSA-93r5-fhx6-vmg9High
    xmldom: Quadratic-time parsing via the malformed-input recovery path — `parseElementStartPart` re-scan and `normalize()` adjacent-text merge
    • >= 0.3.0, <= 0.6.0

    ## Summary `xmldom`'s malformed-input **error-recovery path** has two quadratic-time (O(n²)) behaviors that a single crafted input triggers together, so a tiny, highly compressible document (tens of KB) stalls the Node.js event loop for multiple seconds. It is reachable from `DOMParser.parseFromString` under **default options** — i.e. from unauthenticated, network-delivered XML — making this an unauthenticated denial of service. One of the two behaviors, the `normalize()` adjacent-text merge, is **additionally reachable programmatically** — via a plain `normalize()` call on a DOM built with a

    CVE: CVE-2026-83614

  • GHSA-965w-775f-mr7gHigh
    xmldom: Quadratic-memory consumption
    • >= 0.1.5, <= 0.6.0

    ## Summary When an element declares a namespace prefix, xmldom copies the entire in-scope namespace map into a fresh object and keeps that copy on the element while it is open on the parse stack. A crafted document that nests N elements, each declaring one unique prefix, therefore drives the parser to hold on the order of N(N+1)/2 = **O(N²) namespace-map entries at its peak**, so a small, highly compressible input exhausts the heap. Parsing runs under default options on untrusted, network-delivered XML, so a sub-megabyte payload can OOM-crash the process before any application-level validatio

    CVE: CVE-2026-83615

  • GHSA-c7q8-3ch8-vqpvHigh
    xmldom: Processing Instruction Target Injection Bypasses requireWellFormed
    • <= 0.6.0

    ## Summary `Document.createProcessingInstruction()` in `@xmldom/xmldom` performs no validation on the `target` parameter. The `requireWellFormed: true` serializer option validates only for `:` in the target and a case-insensitive `xml` prefix, but does not check for `>` characters. A `>` in the target breaks the processing instruction boundary (`<?...?>`), allowing injection of arbitrary content into the serialized XML output. ## Details `Document.createProcessingInstruction(target, data)` at `lib/dom.js` around line 2413 accepts any string as the `target` parameter and stores it on the PI

    CVE: CVE-2026-83616

  • GHSA-w2rr-34g9-rvrjHigh
    xmldom: Element name injection via createElement() bypasses requireWellFormed
    • <= 0.6.0

    ## Summary `Document.createElement()` in `@xmldom/xmldom` accepts arbitrary strings as the `tagName` parameter with zero validation. The serializer emits the tag name verbatim into XML/HTML output. Critically, the `requireWellFormed: true` serializer option — the recommended mitigation from CVE-2026-41672, CVE-2026-41674, and CVE-2026-34601 — did NOT catch this, making it a bypass of the existing security controls. An attacker who controls the element name string can inject arbitrary attributes (including event handlers) into the serialized output, leading to XSS when the output is consumed

    CVE: CVE-2026-83607

  • GHSA-6gmq-8vp8-gcm6Moderate
    xmldom: XML fragment injection via invalid EntityReference.nodeName during requireWellFormed serialization
    • <= 0.6.0

    ## Summary An `EntityReference` node can be created with an invalid, attacker-controlled name through `Document.createEntityReference(name)`. When this node is serialized directly with: ```js serializer.serializeToString(ref, { requireWellFormed: true }) ``` the invalid `nodeName` is emitted into the serialized XML fragment without validation or escaping. This can produce real XML markup in the serialized output. In the proof of concept below, the serialized fragment contains `<injected/>`, and reparsing the fragment creates a real `injected` element. --- ## Details The issue appears to

    CVE: CVE-2026-83610

  • GHSA-2v35-w6hq-6mfwHigh
    xmldom: Uncontrolled recursion in XML serialization leads to DoS
    • <= 0.6.0

    ## Summary 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()` / `getElement

    CVE: CVE-2026-41673

Showing 1-10 of 18 vulnerabilities