Back to Blog
critical SEVERITY4 min read

fast-xml-parser 4.5.0 XSS: DOCTYPE Entity Injection in XML.parse()

fast-xml-parser versions 4.5.0 and earlier fail to sanitize DOCTYPE entity declarations during XML parsing, allowing attackers to inject JavaScript through crafted XML payloads. The vulnerability permits reflected XSS in applications that process untrusted XML input. Upgrading to version 5.7.0 eliminates the unsafe entity expansion path.

O
By Orbis AppSec
•Technically reviewed by Anupam Mediratta•Published October 9, 2026•Reviewed October 9, 2026

Answer Summary

fast-xml-parser versions 4.5.0 and earlier are affected. An attacker achieves reflected XSS by supplying malicious XML containing DOCTYPE entity declarations that expand into executable JavaScript when rendered. The fix upgrades fast-xml-parser to version 5.7.0, which properly handles entity expansion without unsafe interpolation. CWE is unknown.

Vulnerability at a Glance

cweunknown
fixUpgrade fast-xml-parser to patched version 5.7.0
riskReflected XSS via malicious XML payload processing
languageJavaScript (Node.js/npm)
root causeImproper sanitization of DOCTYPE entity declarations during XML parsing
vulnerabilityCross-Site Scripting (XSS)

Affected Versions

Affected <= 4.5.0
Fixed in 5.7.0 (also patched in 4.5.4, 5.3.5)
Ecosystem npm
CVE / GHSA CVE-2026-25896 / not assigned
CWE unknown

The Vulnerability Explained

The fast-xml-parser library provides high-performance XML parsing for Node.js applications. In versions 4.5.0 and earlier, the parser's handling of DOCTYPE document type declarations contained a critical flaw: external entity references within <!ENTITY> declarations were processed without adequate sanitization, allowing attacker-controlled strings to propagate through the parsed output.

When XMLParser.parse() encounters a DOCTYPE section like:

<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>

The entity &xxe; expands during parsing. The vulnerability arises when this expansion occurs in contexts where the resulting string later reaches a browser's HTML parser without proper encoding. An attacker crafts XML where entity expansion produces a JavaScript payload:

<!DOCTYPE svg [
  <!ENTITY xss "<script>alert('XSS')</script>">
]>
<svg>&xss;</svg>

If the application takes parser.parse(xml).svg and injects it into a webpage's DOM via innerHTML or similar, the script executes. The root cause is that fast-xml-parser 4.5.0 treated expanded entities as trusted content, failing to apply the contextual encoding that would prevent HTML metacharacters from becoming executable code.

Real-world impact is severe for applications that:
- Accept XML uploads from untrusted users
- Transform XML to HTML for display
- Use parsed XML values in server-side rendering templates without additional escaping

The Fix

The remediation upgrades fast-xml-parser to version 5.7.0, which contains hardened entity handling. The change appears in package.json:

-    (no explicit fast-xml-parser dependency)
+    "fast-xml-parser": "5.7.0",

This explicit version pin ensures the dependency tree resolves to a patched release. The bun.lockb update propagates this constraint through the locked dependency graph.

Version 5.7.0 addresses CVE-2026-25896 by:

  1. Restricting external entity resolution — The parser now limits which entity types can trigger network requests or file system access
  2. Context-aware output encoding — Expanded entities are treated as data, not markup, when the output may reach HTML contexts
  3. Stricter DOCTYPE parsing — Malformed or suspicious entity declarations trigger parse errors rather than silent unsafe expansion

The upgrade path is straightforward: no API changes affect standard XMLParser usage. Applications calling new XMLParser().parse(xml) receive identical parsed structures, just without the underlying vulnerability.

Key Takeaways

  • Explicit dependency management matters: The vulnerability existed in a transitive dependency; adding an explicit fast-xml-parser version in package.json forces the secure version even when intermediate packages specify looser ranges.

  • XML parsing requires output-context awareness: Safe parsing isn't just about the parser itself—developers must consider where parsed data flows. The same safe parser can produce vulnerable applications if output encoding is mismatched to the destination context.

  • DOCTYPE is dangerous by default: Modern XML security guidance recommends disabling DTD/DOCTYPE processing entirely when not required. The patched versions make this safer by default, but applications with strict security requirements should still explicitly set processEntities: false where the parser API permits.

  • Lockfile updates are security updates: The bun.lockb change in this fix is as critical as the package.json change—without regenerating the lockfile, the old vulnerable version remains installed.

How Orbis AppSec Detected This

Source: Untrusted XML input reaching XMLParser.parse() via HTTP request bodies, file uploads, or external API responses

Sink: The XMLParser constructor and parse() method in fast-xml-parser versions 4.5.0 and earlier, specifically the internal entity expansion logic triggered by DOCTYPE declarations

Missing control: Absence of version constraints preventing the vulnerable fast-xml-parser 4.5.0 from appearing in the dependency tree; no explicit disabling of entity processing through parser options

CWE: unknown (pending assignment)

Fix: Explicit dependency on fast-xml-parser 5.7.0 in package.json with corresponding lockfile regeneration to eliminate the vulnerable code path

Orbis AppSec detected this vulnerability automatically. Try Orbis AppSec on your repositories to find and fix issues like this.

Conclusion

CVE-2026-25896 demonstrates how a seemingly benign XML parsing utility can become an XSS vector through improper entity handling. The fast-xml-parser 4.5.0 vulnerability specifically exploited the trust boundary between XML entity expansion and HTML rendering contexts—an architectural concern that secure-by-default parser design must address. Upgrading to version 5.7.0 closes this gap, but the broader lesson stands: any data transformation that crosses trust boundaries requires explicit validation of both the transformation and its output encoding.

Prevention and further reading

Frequently Asked Questions

Does fast-xml-parser 5.7.0 change the default behavior for DOCTYPE processing, or just sanitize the output?

Version 5.7.0 implements safer entity handling that prevents the expansion of external entities into contexts where they can execute as JavaScript, without requiring developers to explicitly disable DOCTYPE parsing.

If my application uses fast-xml-parser 4.5.0 but never renders parsed XML content to HTML, am I still vulnerable?

The XSS risk manifests when parsed content reaches a browser context; however, the underlying unsafe entity expansion in 4.5.0 could potentially affect other output contexts depending on application logic, making the upgrade to 5.7.0 recommended regardless.

Why does the fix PR add fast-xml-parser 5.7.0 to package.json when the advisory mentions versions 4.5.4 and 5.3.5 as patched?

The PR proactively upgrades to 5.7.0, the latest stable release at the time of the fix, which incorporates the CVE-2026-25896 patch along with additional hardening; versions 4.5.4 and 5.3.5 were the minimal patched releases identified in the advisory.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #2

Related Articles

high

sanitizeBangumiHtml() XSS Fix: insertAdjacentHTML RCE via JSON

A high-severity cross-site scripting vulnerability existed where untrusted JSON data from bangumis.json was rendered directly into the DOM using insertAdjacentHTML without sanitization. An attacker who could modify this external data source could execute arbitrary JavaScript in visitors' browsers. The fix introduces a dedicated sanitizeBangumiHtml() function that strips script tags, event handlers, and javascript: URLs before insertion.

high

form.js jQuery Selector Construction: CWE-79 Quote-Breaking Fix

A defense-in-depth fix in the form.js initialization routine eliminates a jQuery selector injection vector where user-controlled category data was concatenated directly into a string literal. The vulnerable pattern at lines 47-48 of the form handler could allow malicious content to break out of the selector's quoted context and execute arbitrary jQuery methods.

high

ItemPicker `_commitTraitInput` XSS via Unescaped Trait Chip Rendering

The `_commitTraitInput` function in ItemPicker accepted arbitrary user input for trait values without sanitization, then rendered those values directly into HTML chip elements through `_updateList`. An attacker could inject malicious JavaScript payloads that executed when trait chips were displayed. The fix applies a strict whitelist filter removing all non-alphanumeric characters except spaces and hyphens.

high

formatObject() Leaves localStorage Keys Unescaped Before innerHTML

The `formatObject()` pretty-printer used to build the key-configuration storage viewer interpolated object keys and array key/value pairs directly into an HTML string that is later assigned with `innerHTML`. Only string *values* were passed through `escapeHtml()`, so a crafted key name persisted in `localStorage` could execute script every time a user opened the storage viewer. The fix wraps the index-pair branch and the object-key branch in `escapeHtml()`, keeping the raw path only for non-colo

high

Voice Assistant Widget XSS: Unsanitized Bot Messages Execute in

The voice assistant widget's `appendMessage` function had a critical cross-site scripting (XSS) vulnerability where bot messages were inserted directly into the DOM without sanitization, while user messages were escaped. An attacker controlling bot responses could inject and execute arbitrary JavaScript in the user's browser context. The fix applies HTML escaping to all message types uniformly.

critical

Music Studio App Express Server: CWE-287 Authentication Bypass via

A critical authentication bypass vulnerability in a music studio application's Express server allowed remote attackers to access API endpoints despite the intended localhost-only restriction. The localRequest middleware validated the Host header but failed to verify the actual remote socket address, enabling trivial bypasses in containerized and multi-user environments.