Skip to content

chore(deps): update dependency @xmldom/xmldom to v0.8.12 [security]#2727

Open
renovate-bot wants to merge 1 commit intogoogleapis:mainfrom
renovate-bot:renovate/npm-xmldom-xmldom-vulnerability
Open

chore(deps): update dependency @xmldom/xmldom to v0.8.12 [security]#2727
renovate-bot wants to merge 1 commit intogoogleapis:mainfrom
renovate-bot:renovate/npm-xmldom-xmldom-vulnerability

Conversation

@renovate-bot
Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@xmldom/xmldom 0.8.60.8.12 age confidence

GitHub Vulnerability Alerts

CVE-2026-34601

Summary

@xmldom/xmldom allows attacker-controlled strings containing the CDATA terminator ]]> to be inserted into a CDATASection node. During serialization, XMLSerializer emitted the CDATA content verbatim without rejecting or safely splitting the terminator. As a result, data intended to remain text-only became active XML markup in the serialized output, enabling XML structure
injection and downstream business-logic manipulation.

The sequence ]]> is not allowed inside CDATA content and must be rejected or safely handled during serialization. (MDN Web Docs)

Attack surface

Document.createCDATASection(data) is the most direct entry point, but it is not the only one. The WHATWG DOM spec intentionally does not validate ]]> in mutation methods — only createCDATASection carries that guard. The following paths therefore also allow ]]> to enter a CDATASection node and reach the serializer:

  • CharacterData.appendData()
  • CharacterData.replaceData()
  • CharacterData.insertData()
  • Direct assignment to .data
  • Direct assignment to .textContent

(Note: assigning to .nodeValue does not update .data in this implementation — the serializer reads .data directly — so .nodeValue is not an exploitable path.)

Parse path

Parsing XML that contains a CDATA section is not affected. The SAX parser's non-greedy CDSect regex stops at the first ]]>, so parsed CDATA data never contains the terminator.


Impact

If an application uses xmldom to generate "trusted" XML documents that embed untrusted user input inside CDATA (a common pattern in exports, feeds, SOAP/XML integrations, etc.), an attacker can inject additional XML elements/attributes into the generated document.

This can lead to:

  • Integrity violation of generated XML documents.
  • Business-logic injection in downstream consumers (e.g., injecting <approved>true</approved>, <role>admin</role>, workflow flags, or other security-relevant elements).
  • Unexpected privilege/workflow decisions if downstream logic assumes injected nodes cannot appear.

This issue does not require malformed parsers or browser behavior; it is caused by serialization producing attacker-influenced XML markup.


Root Cause (with file + line numbers)

File: lib/dom.js

1. No validation in createCDATASection

createCDATASection: function (data) accepts any string and appends it directly.

  • Lines 2216–2221 (0.9.8)

2. Unsafe CDATA serialization

Serializer prints CDATA sections as:

<![CDATA[ + node.data + ]]>

without handling ]]> in the data.

  • Lines 2919–2920 (0.9.8)

Because CDATA content is emitted verbatim, an embedded ]]> closes the CDATA section early and the remainder of the attacker-controlled payload is interpreted as markup in the serialized XML.


Proof of Concept — Fix A: createCDATASection now throws

On patched versions, passing ]]> directly to createCDATASection throws InvalidCharacterError instead of silently accepting the payload:

const { DOMImplementation } = require('./lib');

const doc = new DOMImplementation().createDocument(null, 'root', null);
try {
  doc.createCDATASection('SAFE]]><injected attr="pwn"/>');
  console.log('VULNERABLE — no error thrown');
} catch (e) {
  console.log('FIXED — threw:', e.name); // InvalidCharacterError
}

Expected output on patched versions:

FIXED — threw: InvalidCharacterError

Proof of Concept — Fix B: mutation vector now safe

On patched versions, injecting ]]> via a mutation method (appendData, replaceData, .data =, .textContent =) no longer produces injectable output. The serializer splits the terminator so the result round-trips as safe text:

const { DOMImplementation, XMLSerializer } = require('./lib');
const { DOMParser } = require('./lib');

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

// Start with safe data, then mutate to include the terminator
const cdata = doc.createCDATASection('safe');
doc.documentElement.appendChild(cdata);
cdata.appendData(']]><injected attr="pwn"/><more>TEXT</more><![CDATA[');

const out = new XMLSerializer().serializeToString(doc);
console.log('Serialized:', out);

const reparsed = new DOMParser().parseFromString(out, 'text/xml');
const injected = reparsed.getElementsByTagName('injected').length > 0;
console.log('Injected element found in reparsed doc:', injected);
// VULNERABLE: true  |  FIXED: false

Expected output on patched versions:

Serialized: <root><![CDATA[safe]]]]><![CDATA[><injected attr="pwn"/><more>TEXT</more><![CDATA[]]></root>
Injected element found in reparsed doc: false

Fix Applied

Both mitigations were implemented:

Option A — Strict/spec-aligned: reject ]]> in createCDATASection()

Document.createCDATASection(data) now throws InvalidCharacterError (per the WHATWG DOM spec) when data contains ]]>. This closes the direct entry point.

Code that previously passed a string containing ]]> to createCDATASection and relied on the silent/unsafe behaviour will now receive InvalidCharacterError. Use a mutation method such as appendData if you intentionally need ]]> in a CDATASection node's data (the serializer split in Option B will keep the output safe).

Option B — Defensive serialization: split the terminator during serialization

XMLSerializer now replaces every occurrence of ]]> in CDATA section data with the split sequence ]]]]><![CDATA[> before emitting. This closes all mutation-vector paths that Option A alone cannot guard, and means the serialized output is always well-formed XML regardless of how ]]> entered the node.


Release Notes

xmldom/xmldom (@​xmldom/xmldom)

v0.8.12

Compare Source

Fixed
  • preserve trailing whitespace in ProcessingInstruction data #962 / #42
  • Security: createCDATASection now throws InvalidCharacterError when data contains "]]>", as required by the WHATWG DOM spec. GHSA-wh4c-j3r5-mjhp
  • Security: XMLSerializer now splits CDATASection nodes whose data contains "]]>" into adjacent CDATA sections at serialization time, preventing XML injection via mutation methods (appendData, replaceData, .data =, .textContent =). GHSA-wh4c-j3r5-mjhp

Code that passes a string containing "]]>" to createCDATASection and relied on the previously unsafe behavior will now receive InvalidCharacterError. Use a mutation method such as appendData if you intentionally need "]]>" in a CDATASection node's data.

Thank you,
@​thesmartshadow,
@​stevenobiajulu,
for your contributions

v0.8.11

Compare Source

Fixed
  • update ownerDocument when moving nodes between documents #933 / #932

Thank you, @​shunkica, for your contributions

v0.8.10

Compare Source

Fixed
  • dom: prevent iteration over deleted items #514/ #499

Thank you, @​qtow, for your contributions

v0.8.9

Compare Source

Fixed
  • Set nodeName property in ProcessingInstruction #509 / #505

Thank you, @​cjbarth, for your contributions

v0.8.8

Compare Source

Fixed
  • extend list of HTML entities #489

Thank you, @​zorkow, for your contributions

v0.8.7

Compare Source

Fixed
  • properly parse closing where the last attribute has no value #485 / #486

Thank you, @​bulandent, for your contributions


Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate-bot renovate-bot requested review from a team as code owners April 1, 2026 05:10
@product-auto-label product-auto-label bot added the size: xs Pull request size is extra small. label Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: xs Pull request size is extra small.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants