CVE-2026-41672: xmldom: XML node injection through unvalidated comment serialization

Published Apr 22, 2026
·
Updated

Summary

The package allows attacker-controlled comment content to be serialized into XML without validating or neutralizing comment breaking sequences. As a result, an attacker can terminate the comment early and inject arbitrary XML nodes into the serialized output.

---

Details

The issue is in the DOM construction and serialization flow for comment nodes.

When createComment(data) is called, the supplied string is stored as comment data through the generic character-data handling path. That content is kept as-is. Later, when the document is serialized, the serializer writes comment nodes by concatenating the XML comment delimiters with the stored node.data value directly.

That behavior is unsafe because XML comments are a syntax-sensitive context. If attacker-controlled input contains a sequence that closes the comment, the serializer does not preserve it as literal comment text. Instead, it emits output where the remainder of the payload is treated as live XML markup.

This is a real injection bug, not a formatting issue. The serializer already applies context-aware handling in other places, such as escaping text nodes and rewriting unsafe CDATA terminators. Comment content does not receive equivalent treatment. Because of that gap, untrusted data can break out of the comment boundary and modify the structure of the final XML document.

---

PoC

js const { DOMImplementation, DOMParser, XMLSerializer } = require('@xmldom/xmldom');

const doc = new DOMImplementation().createDocument(null, 'root', null);

doc.documentElement.appendChild( doc.createComment('--><injected attr="1"/><!--') );

const xml = new XMLSerializer().serializeToString(doc); console.log(xml); // <root><!----><injected attr="1"/><!----></root>

const reparsed = new DOMParser().parseFromString(xml, 'text/xml'); console.log(reparsed.documentElement.childNodes.item(1).nodeName); // injected

---

Impact

An application that uses the package to build XML from untrusted input can be made to emit attacker-controlled elements outside the intended comment boundary. That allows the attacker to alter the meaning and structure of generated XML documents.

In practice, this can affect any workflow that generates XML and then stores it, forwards it, signs it, or hands it to another parser. Realistic targets include XML-based configuration, policy documents, and message formats where downstream consumers trust the serialized structure.

---

Disclosure

This vulnerability was publicly disclosed at 2026-04-06T11:25:07Z via xmldom/xmldom#987, which was subsequently closed without being merged.

---

Fix Applied

⚠ Opt-in required. Protection is not automatic. Existing serialization calls remain vulnerable unless { requireWellFormed: true } is explicitly passed. Applications that pass untrusted data to createComment() or mutate comment nodes with untrusted input (via appendData, insertData, replaceData, .data =, or .textContent =) should audit all serializeToString() call sites and add the option.

XMLSerializer.serializeToString() now accepts an options object as a second argument. When { requireWellFormed: true } is passed, the serializer throws InvalidStateError before emitting a Comment node whose .data would produce malformed XML.

On @xmldom/xmldom ≥ 0.9.10, the full W3C DOM Parsing §3.2.1.4 check is applied: throws if .data contains -- anywhere, ends with -, or contains characters outside the XML Char production.

On @xmldom/xmldom ≥ 0.8.13 (LTS), only the --> injection sequence is checked. The 0.8.x SAX parser accepts comments containing -- (without >), so throwing on bare -- would break a previously-working round-trip on that branch. The --> check is sufficient to prevent injection.

PoC — fixed path

js const { DOMImplementation, XMLSerializer } = require('@xmldom/xmldom');

const doc = new DOMImplementation().createDocument(null, 'root', null); doc.documentElement.appendChild(doc.createComment('--><injected attr="1"/><!--'));

// Default (unchanged): verbatim — injection present const unsafe = new XMLSerializer().serializeToString(doc); console.log(unsafe); // <root><!----><injected attr="1"/><!----></root>

// Opt-in guard: throws InvalidStateError before serializing try { new XMLSerializer().serializeToString(doc, { requireWellFormed: true }); } catch (e) { console.log(e.name, e.message); // InvalidStateError: The comment node data contains "--" or ends with "-" (0.9.x) // InvalidStateError: The comment node data contains "-->" (0.8.x — only --> is checked) }

Why the default stays verbatim

The W3C DOM Parsing and Serialization spec §3.2.1.4 defines a require well-formed flag whose default value is false. With the flag unset, the spec explicitly permits serializing ill-formed comment content verbatim — this is also the behavior of browser implementations (Chrome, Firefox, Safari): new XMLSerializer().serializeToString(doc) produces the injection sequence without error in all major browsers.

Unconditionally throwing would be a behavioral breaking change with no spec justification. The opt-in requireWellFormed: true flag allows applications that require injection safety to enable strict mode without breaking existing deployments.

Residual limitation

The fix operates at serialization time only. There is no creation-time check in createComment — the spec does not require one for comment data. Any path that leads to a Comment node with -- in its data (createComment, appendData, .data =, etc.) produces a node that serializes safely only when { requireWellFormed: true } is passed to serializeToString.

Other sources

xmldom is a pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module. In @xmldom/xmldom prior to versions 0.9.10 and 0.8.13 and xmldom version 0.6.0 and prior, the package allows attacker-controlled comment content to be serialized into XML without validating or neutralizing comment-breaking sequences. As a result, an attacker can terminate the comment early and inject arbitrary XML nodes into the serialized output. This issue has been patched in versions @xmldom/xmldom versions 0.9.10 and 0.8.13.

— MITRE

Affected Software

3 affected componentsFixes available
npm/xmldom<=0.6.0
npm/@xmldom/xmldom>=0.9.0<0.9.10
0.9.10
npm/@xmldom/xmldom<0.8.13
0.8.13

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/@xmldom/xmldom to a version that resolves this vulnerability.

    Fixed in 0.9.10
  2. Upgrade

    Upgrade npm/@xmldom/xmldom to a version that resolves this vulnerability.

    Fixed in 0.8.13
  3. Upgrade

    Upgrade @xmldom/xmldom to a version that resolves this vulnerability.

    Fixed in 0.9.10
  4. Upgrade

    Upgrade @xmldom/xmldom to a version that resolves this vulnerability.

    Fixed in 0.8.13
  5. Configuration

    When calling `serializeToString()` for documents that may contain attacker-controlled comment node content, pass the options object `{ requireWellFormed: true }` (the serializer throws InvalidStateError before emitting a comment node whose `.data` would break comment syntax).

    XMLSerializer (xmldom/@xmldom/xmldom) requireWellFormed = true
  6. Configuration

    Audit all paths that call `createComment`, `appendData`, `insertData`, `replaceData`, assign to `.data`, or `.textContent` with untrusted input so that comment node `.data` cannot contain comment-breaking sequences like `--` (or ends with `-`) before serializing.

    createComment / comment node data handling comment node data validation = require comment data to be well-formed (no `--`, no trailing `-`, only XML Char production)

Event History

Apr 22, 2026
Advisory Published
via GitHub·08:16 PM
Data Sourced
via GitHub·08:16 PM
DescriptionWeaknessAffected Software
May 7, 2026
CVE Published
via MITRE·03:36 AM
Data Sourced
via MITRE·03:36 AM
DescriptionWeakness
Data Sourced
via NVD·04:16 AM
DescriptionSeverityWeakness
Data Sourced
via Red Hat·05:02 AM
DescriptionSeverityAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-41672?

CVE-2026-41672 is considered a significant vulnerability due to its potential to compromise XML serialization by allowing arbitrary XML injection.

2

How do I fix CVE-2026-41672?

To fix CVE-2026-41672, update the affected package 'xmldom' to version 0.6.1 or later, or '@xmldom/xmldom' to version 0.9.10 or 0.8.13.

3

What types of software are affected by CVE-2026-41672?

CVE-2026-41672 affects versions of the 'xmldom' package up to 0.6.0 and '@xmldom/xmldom' versions from 0.9.0 up to 0.9.10 and below 0.8.13.

4

What kind of attack can occur due to CVE-2026-41672?

The vulnerability can be exploited to perform XML injection attacks by allowing attackers to inject arbitrary XML nodes.

5

Is CVE-2026-41672 a remote attack vector?

Yes, CVE-2026-41672 can be exploited remotely since it allows attacker-controlled content to manipulate XML serialization.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203