GitHub Security Advisory: GHSA-wh4c-j3r5-mjhp
Package: @xmldom/xmldom (NPM)
Severity: HIGH (CVSS 7.5)
CWE: CWE-91: XML Injection (aka Blind XPath Injection)
Vulnerable versions: >= 0.9.0, < 0.9.9
Patched in: 0.9.9

Summary: xmldom: XML injection via unsafe CDATA serialization allows attacker-controlled markup insertion

Details:
## 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](https://developer.mozilla.org/))

### 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 `create