Back to Blog
high SEVERITY8 min read

How Denial of Service via Unbounded Data Happens in JavaScript and how to fix it

CVE-2025-58754 is a high-severity Denial of Service vulnerability in the popular axios HTTP client library, caused by the absence of a data size check on incoming response or request payloads. An attacker who can influence the size of data processed by axios could exhaust server memory or CPU, bringing down dependent Node.js applications. The fix upgrades axios from version 1.8.4 to 1.18.0, closing the unbounded data processing path.

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

Answer Summary

CVE-2025-58754 is a high-severity Denial of Service (DoS) vulnerability in the axios JavaScript HTTP client library (CWE-400: Uncontrolled Resource Consumption). The root cause is a missing data size check, meaning axios would process arbitrarily large payloads without any limit, allowing an attacker to exhaust memory or CPU in any Node.js application that uses axios to fetch or relay user-influenced data. The fix is to upgrade axios from 1.8.4 to 1.18.0 (or 0.28.x to 0.30.2 for the legacy branch), which introduces proper size validation before processing response or request data.

Vulnerability at a Glance

cweCWE-400
fixUpgrade axios from 1.8.4 → 1.18.0 (specifier bumped from ^1.7.9 to ^1.18.0 in package.json and pnpm-lock.yaml)
riskAttackers can exhaust server memory or CPU by sending or triggering arbitrarily large HTTP payloads
languageJavaScript / TypeScript (Node.js)
root causeaxios lacked a data size check before processing HTTP response or request bodies
vulnerabilityDenial of Service via Uncontrolled Resource Consumption

How Denial of Service via Unbounded Data Happens in JavaScript and how to fix it


The Vulnerability at a Glance

Field Detail
CVE CVE-2025-58754
Severity High
CWE CWE-400 — Uncontrolled Resource Consumption
Affected package axios 1.8.4 (and legacy branch < 0.30.2)
Fixed version axios 1.18.0 / 0.30.2
Language JavaScript / TypeScript (Node.js)

Introduction

The pnpm-lock.yaml file in this project pinned axios at version 1.8.4 — a version that ships without any check on how large a response or request body can be before axios starts processing it. That single missing guard is the entire attack surface for CVE-2025-58754. Any application that uses axios to fetch data from a URL that an attacker can influence — or that relays user-supplied data through axios — is exposed to a resource exhaustion attack that can silently consume all available memory or CPU until the Node.js process crashes or becomes unresponsive.

This post walks through exactly what the vulnerability is, how it can be exploited in practice, and what the upgrade from ^1.7.9 to ^1.18.0 actually changes.


The Vulnerability Explained

What is CWE-400 (Uncontrolled Resource Consumption)?

CWE-400 describes a class of bugs where software allocates or processes a resource — memory, CPU time, file handles, network buffers — in direct proportion to attacker-controlled input, with no upper bound. The result is that a sufficiently large or numerous input will exhaust the resource and deny service to legitimate users.

In axios's case, the resource is the in-memory buffer used to accumulate an HTTP response (or request) body. Before the fix, axios would keep reading and buffering data until the stream ended, regardless of how many bytes had already been consumed.

The Vulnerable Dependency Declaration

Before the fix, package.json specified:

"dependencies": {
    "axios": "^1.7.9"
}

And pnpm-lock.yaml resolved this to the exact installed version:

axios:
  specifier: ^1.7.9
  version: 1.8.4

The ^1.7.9 semver range means "any version ≥ 1.7.9 and < 2.0.0." Because axios 1.8.4 fell inside that range, pnpm locked to it. The problem is that 1.8.4 does not include the data size check introduced in later releases.

How the Exploit Works

Imagine this application uses axios to proxy or fetch a URL supplied by a user:

// Simplified example of a vulnerable usage pattern
app.get('/fetch', async (req, res) => {
  const url = req.query.url;
  const response = await axios.get(url); // axios 1.8.4 — no size limit
  res.json(response.data);
});

An attacker points url at a server they control that streams an infinitely large (or multi-gigabyte) response body. Axios in version 1.8.4 has no mechanism to say "this response is too big — abort." It keeps allocating Node.js heap memory to buffer the incoming bytes. The Node.js process's heap grows until:

  1. The OS kills the process with an out-of-memory signal, or
  2. The garbage collector thrashes and CPU utilization spikes to 100%, or
  3. The heap limit is hit and Node.js throws a fatal JavaScript heap out of memory error.

In all three cases, every other request being handled by the same process is dropped. The application is down.

Even without a proxy scenario, any application that fetches data from third-party APIs could be targeted if an attacker can influence the API endpoint, inject a malicious redirect, or perform a DNS rebinding attack to point a trusted hostname at a malicious server.

Why This Is Rated High Severity

  • No authentication required: The attacker only needs network access to the application or to a server the application fetches from.
  • Single request can be sufficient: One well-crafted HTTP response can exhaust memory.
  • No crash recovery by default: Node.js single-threaded event loop means one blocked/crashed process takes down all concurrent users.
  • Widely used library: axios is one of the most downloaded npm packages, meaning the blast radius across the ecosystem is enormous.

The Fix

What Changed in package.json

-  "axios": "^1.7.9"
+  "axios": "^1.18.0"

The semver range was bumped to ^1.18.0, which means pnpm will now resolve to axios 1.18.0 or any compatible patch/minor above it — all of which include the size-check fix.

What Changed in pnpm-lock.yaml

 axios:
-  specifier: ^1.7.9
-  version: 1.8.4
+  specifier: ^1.18.0
+  version: 1.18.0

The lock file now pins to 1.18.0 exactly. This is the critical file from a security perspective: even if package.json had been updated without regenerating the lock file, the old 1.8.4 would still have been installed by pnpm install --frozen-lockfile. Both files must be updated together, which is exactly what this PR does.

What axios 1.18.0 Actually Fixes

Axios 1.18.0 introduces an internal check on the size of data being accumulated before it is parsed or returned to the caller. When a response body exceeds a configurable threshold, axios aborts the stream and rejects the promise with an appropriate error — rather than silently buffering indefinitely. This gives application code a chance to handle the error gracefully instead of running out of memory.

The security improvement is concrete: the unbounded allocation path is replaced with a bounded one, and the attacker's ability to dictate memory consumption is removed.

Why Both Files Matter

File Role Why it needed updating
package.json Declares the acceptable version range Old range ^1.7.9 still permitted 1.8.4 to be installed
pnpm-lock.yaml Pins the exact installed version Without updating this, pnpm install would reinstall 1.8.4 regardless of package.json

Prevention & Best Practices

1. Keep Dependency Lock Files in Version Control and CI

pnpm-lock.yaml (and equivalents like package-lock.json or yarn.lock) must be committed and used in CI with --frozen-lockfile. This ensures the exact vulnerable version is flagged by SCA scanners, as happened here.

2. Run SCA Scanning on Lock Files

Tools like Trivy, Snyk, and Socket scan lock files for known CVEs. Trivy flagged this exact pattern (CVE-2025-58754 in pnpm-lock.yaml) automatically. Integrate these scanners into your CI pipeline and block merges on high-severity findings.

3. Use maxContentLength and maxBodyLength in axios

Even on patched versions, you can add defense-in-depth by explicitly configuring axios size limits:

const axios = require('axios');

const client = axios.create({
  maxContentLength: 10 * 1024 * 1024,  // 10 MB response limit
  maxBodyLength: 5 * 1024 * 1024,       // 5 MB request body limit
});

This makes your intent explicit in code and provides a safety net if a future regression slips through.

4. Apply the Principle of Least Privilege to HTTP Clients

If your application fetches URLs, validate that the URL belongs to an allowlist of trusted domains before passing it to axios. This limits the attacker's ability to redirect axios at a malicious server in the first place.

5. Monitor for Heap Growth

Use Node.js APM tools (Datadog, New Relic, or even the built-in process.memoryUsage()) to alert on abnormal heap growth. Sudden spikes in heapUsed during HTTP fetch operations are a signal worth investigating.

Relevant Standards

  • OWASP Top 10 A05:2021 – Security Misconfiguration: Outdated or misconfigured dependencies fall under this category.
  • CWE-400: Uncontrolled Resource Consumption — the direct CWE for this vulnerability.
  • OWASP Dependency-Check / OWASP Cheat Sheet: Vulnerable and Outdated Components: https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html

Key Takeaways

  • Pinning to 1.8.4 in pnpm-lock.yaml was the concrete attack surface: The lock file, not just package.json, is what determines what actually gets installed. Both must be updated together.
  • axios's missing data size check in versions < 1.18.0 / < 0.30.2 is the root cause: This is not a generic "keep dependencies updated" lesson — this specific version boundary (1.8.4 → 1.18.0) is where the protection was added.
  • A single unbounded HTTP fetch can crash a Node.js process: Because the event loop is single-threaded, one memory-exhausting request affects all concurrent users simultaneously.
  • maxContentLength and maxBodyLength provide defense-in-depth: Even after upgrading, explicitly setting these axios options makes your size expectations part of your code contract.
  • SCA tools scanning lock files (not just package.json) are essential: Trivy found this because it scanned pnpm-lock.yaml where the exact resolved version 1.8.4 was recorded.

How Orbis AppSec Detected This

  • Source: HTTP response data received by axios when fetching from a user-influenced or attacker-controlled URL
  • Sink: axios's internal response body accumulation buffer in axios@1.8.4, which lacked any size boundary before writing to memory
  • Missing control: No maximum data size check on the response/request body stream prior to buffering and parsing
  • CWE: CWE-400 — Uncontrolled Resource Consumption
  • Fix: Upgraded the axios specifier in package.json from ^1.7.9 to ^1.18.0 and regenerated pnpm-lock.yaml to resolve to 1.18.0, which includes the upstream data size validation.

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-2025-58754 is a sharp reminder that a single missing bounds check in a widely-used HTTP client library can turn any fetch call into a denial-of-service vector. The vulnerability in axios 1.8.4 required no special privileges, no complex payload crafting, and no code changes in the application itself — just a large enough HTTP response body. The fix is straightforward: upgrade to axios 1.18.0, update both package.json and pnpm-lock.yaml, and add explicit maxContentLength/maxBodyLength configuration as a belt-and-suspenders measure. Integrate SCA scanning into your CI pipeline so the next CVE in a transitive dependency is caught before it reaches production.


References

Frequently Asked Questions

What is a Denial of Service via uncontrolled resource consumption?

It is an attack where a library or application processes arbitrarily large or numerous inputs without any limit, allowing an attacker to exhaust memory, CPU, or other resources until the service becomes unavailable.

How do you prevent uncontrolled resource consumption in Node.js HTTP clients?

Always enforce maximum payload size limits when reading HTTP response or request bodies, and keep HTTP client libraries like axios up to date so that upstream size-check patches are applied.

What CWE is this axios DoS vulnerability?

CWE-400 — Uncontrolled Resource Consumption, which covers situations where a program does not limit the amount of resources it allocates or processes in response to external input.

Is rate limiting alone enough to prevent this kind of DoS?

No. Rate limiting controls the frequency of requests but does not constrain the size of individual payloads. You also need per-request data size limits inside the HTTP client or application layer.

Can static analysis detect this kind of vulnerability?

Yes. Trivy and similar SCA (Software Composition Analysis) tools flag known-vulnerable dependency versions in lock files like pnpm-lock.yaml, which is exactly how CVE-2025-58754 was discovered here.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #3

Related Articles

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 dependabot-missing-cooldown happens in GitHub Actions/Node.js and how to fix it

The repository's `.github/dependabot.yml` had no cooldown period configured, meaning Dependabot could immediately propose updates to newly published package versions with zero time for the community to flag malware or instability. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` ecosystems, forcing a 7-day waiting period before new releases are surfaced as update PRs.

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.