Back to Blog
medium SEVERITY5 min read

How XML Entity Expansion Denial of Service happens in Node.js and how to fix it

A critical denial of service vulnerability (CVE-2026-33036) was discovered in fast-xml-parser versions prior to 5.5.6 and 4.5.5, allowing attackers to bypass entity expansion limits and crash Node.js applications through malicious XML payloads. This fix upgrades the dependency in the scripts directory to patched versions, protecting build pipelines and any runtime XML processing from resource exhaustion attacks.

O
By Orbis AppSec
Published August 5, 2026Reviewed August 5, 2026

Answer Summary

CVE-2026-33036 is a high-severity XML Entity Expansion (Billion Laughs) denial of service vulnerability in fast-xml-parser for Node.js, mapped to CWE-776. Attackers can craft XML documents that bypass entity expansion protections, causing exponential memory consumption and application crashes. The fix is to upgrade fast-xml-parser to version 5.5.6 or 4.5.5, which properly enforces entity expansion limits.

Vulnerability at a Glance

cweCWE-776
fixUpgrade fast-xml-parser to version 5.5.6 or 4.5.5
riskApplication crash and resource exhaustion via malicious XML
languageJavaScript (Node.js)
root causeInsufficient entity expansion limits in fast-xml-parser < 5.5.6
vulnerabilityXML Entity Expansion Denial of Service

Introduction

In the scripts/package-lock.json file, the build pipeline depended on fast-xml-parser version 5.3.4—a popular XML parsing library used across thousands of Node.js projects. However, Trivy security scanner flagged this dependency for CVE-2026-33036, a high-severity vulnerability that allows attackers to bypass XML entity expansion protections and trigger denial of service conditions.

The scripts/lib/larkImageDownloader.js file and related build tooling process external data, making this vulnerability particularly concerning. While the exact reachability wasn't confirmed, the presence of a vulnerable XML parser in the dependency tree creates unnecessary risk, especially in CI/CD environments where build scripts process various input formats.

The Vulnerability Explained

What is XML Entity Expansion?

XML Entity Expansion, commonly known as the "Billion Laughs" attack or XML bomb, exploits how XML parsers handle entity definitions. In XML, you can define entities that reference other entities, creating a nested structure:

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!-- ... continues nesting ... -->
]>
<root>&lol9;</root>

When parsed, this small document expands exponentially—a few kilobytes of XML can expand to gigabytes of memory, crashing the application.

The Specific Vulnerability in fast-xml-parser

CVE-2026-33036 reveals that fast-xml-parser versions before 5.5.6 (and 4.5.5 for the 4.x branch) contained a bypass in their entity expansion protections. Even when developers configured limits, attackers could craft XML payloads that circumvented these safeguards.

The vulnerable version in scripts/package-lock.json:

{
  "fast-xml-parser": {
    "version": "5.3.4"
  }
}

Attack Scenario for This Codebase

Consider the build scripts in this repository. The scripts/lib/larkImageDownloader.js handles external integrations with services like Figma and AWS. If any part of the build pipeline processes XML responses—configuration files, API responses, or asset metadata—an attacker could:

  1. Compromise an upstream data source to inject malicious XML
  2. Submit a pull request with a malicious XML configuration file
  3. Manipulate cached responses in the CI/CD environment

The result? Build pipelines crash, deployments stall, and developer productivity grinds to a halt. In severe cases, this could be used as part of a larger attack to create windows of opportunity while teams scramble to restore services.

The Fix

Dependency Upgrade

The fix upgrades fast-xml-parser to version 5.5.6, which properly enforces entity expansion limits. The changes span the dependency management files:

Before (vulnerable):

// scripts/package-lock.json
"fast-xml-parser": {
  "version": "5.3.4"
}

After (patched):

// scripts/package-lock.json
"fast-xml-parser": {
  "version": "5.5.6"
}

New Dependencies for Enhanced Parsing

The fix also introduces supporting packages that fast-xml-parser 5.5.6 relies on for safer parsing:

"node_modules/@nodable/entities": {
  "version": "3.0.0",
  "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-3.0.0.tgz",
  "integrity": "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw=="
}
"node_modules/anynum": {
  "version": "1.0.1",
  "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz",
  "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A=="
}

These packages provide improved entity handling and numeric parsing that support the security fixes in the new fast-xml-parser version.

Yarn Configuration Updates

The fix also adds Yarn configuration (.yarnrc.yml) to ensure consistent dependency resolution:

approvedGitRepositories:
  - "**"

nodeLinker: node-modules

npmMinimalAgeGate: 0

This ensures the patched version is consistently installed across all environments, preventing accidental downgrades.

Key Takeaways

  • fast-xml-parser < 5.5.6 allows entity expansion bypass: Even configured limits could be circumvented, making all XML parsing potentially vulnerable to DoS
  • Build scripts are attack surfaces too: The scripts/ directory processes external data through Figma and AWS integrations—vulnerable dependencies here affect your entire CI/CD pipeline
  • Dependency sub-trees matter: The vulnerability was in scripts/package-lock.json, not the main application—scan all package manifests in your repository
  • Entity expansion differs from XXE: Disabling external entities doesn't protect against internal entity expansion attacks; you need explicit expansion limits
  • Automated scanning catches what manual review misses: Trivy identified this CVE in the dependency tree before it could be exploited

How Orbis AppSec Detected This

  • Source: XML data processed by fast-xml-parser in the scripts dependency tree
  • Sink: fast-xml-parser parse functions that expand XML entities without proper limits
  • Missing control: Entity expansion depth and size limits were bypassable in version 5.3.4
  • CWE: CWE-776 (Improper Restriction of Recursive Entity References in DTDs)
  • Fix: Upgraded fast-xml-parser from 5.3.4 to 5.5.6, which properly enforces entity expansion limits

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-33036 in fast-xml-parser demonstrates why dependency management is a critical security practice. Even well-maintained libraries can have vulnerabilities, and XML parsing has been a persistent source of security issues for decades. By upgrading to fast-xml-parser 5.5.6, this codebase now has proper protection against entity expansion attacks.

Remember: your build scripts and development tooling are part of your attack surface. A compromised CI/CD pipeline can lead to supply chain attacks affecting all downstream users. Keep all dependencies updated, scan regularly, and treat every XML parser configuration as security-sensitive code.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #3607

Related Articles

critical

deleteNestedProperty Prototype Pollution via Dot-Notation Path

The `deleteNestedProperty` function in propertyUtils.ts allowed attackers to manipulate JavaScript object prototypes by passing specially crafted dot-notation paths like `__proto__.polluted`. A fix now blocks dangerous keys before processing, preventing prototype pollution attacks that could affect all objects in the application.

high

How Denial of Service via Infinite Loop Happens in JavaScript Dependencies and How to Fix It

CVE-2026-67213 is a high-severity denial of service vulnerability in nanoid before version 5.1.6 that triggers an infinite loop during random ID generation when processing specially crafted input. We upgraded nanoid across the entire dependency tree to patch this flaw and prevent attackers from freezing application threads. This fix ensures that ID generation remains resilient even when handling adversarial input patterns.

high

How Sensitive Data Exposure happens in Zotero plugins and how to fix it

A high-severity data exposure vulnerability in `Zotero.ts` automatically transmitted complete document metadata—including private notes, attachment paths, and tags—to external LLM services without user consent. The fix replaces broad `item.toJSON()` serialization with explicit field selection, sending only essential bibliographic data.

high

How missing dependency update cooldowns happen in GitHub Dependabot configurations and how to fix it

A semgrep scan flagged `.github/dependabot.yml` for lacking a cooldown period, meaning Dependabot would immediately propose updates to brand-new package versions across npm, Bundler, and Docker ecosystems. The fix adds a `cooldown: default-days: 7` block to every `package-ecosystem` entry, forcing a one-week waiting period before newly published releases are considered — reducing exposure to malicious or unstable package drops.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

critical

How Unbounded WebSocket Message Handling Causes Resource Exhaustion in Node.js and How to Fix It

The WebSocketCrossServerAdapter class in a popular Node.js WebSocket library lacked any rate limiting on inbound messages, allowing attackers to flood Redis nodes and WebSocket servers with high-volume traffic. The fix introduces a configurable `rateLimit` option that caps messages per connection per second, preventing resource exhaustion while preserving legitimate functionality.