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 Unbounded Intermediate Arrays happens in JavaScript and how to fix it

CVE-2026-69152 is a high-severity Denial of Service vulnerability in the `brace-expansion` npm package (versions prior to 1.1.18/2.1.4/3.0.6/5.0.9) that allows attackers to crash a Node.js application by crafting glob patterns that generate unbounded intermediate arrays, effectively bypassing the earlier CVE-2026-14257 mitigation. The fix upgrades `brace-expansion` from 1.1.14 to 1.1.18 in `frontend/package-lock.json`, closing the bypass and restoring safe memory bounds during pattern expansion.

high

How Quadratic CPU Consumption happens in JavaScript YAML parsing and how to fix it

A high-severity denial-of-service vulnerability (GHSA-5p4m-2wfm-xmqj) was discovered in js-yaml affecting both the 3.x and 4.x branches, where parsing YAML documents containing `!!omap` tags triggers quadratic CPU consumption. The fix upgrades js-yaml from `^4.1.1` to `5.2.0` in the project's GitHub Actions workflow dependencies, closing the attack surface for any untrusted YAML input processed by CI/CD tooling.

critical

How Missing Rate Limiting happens in Express.js and how to fix it

Two public API endpoints in `server.js` — `/api/health` and `/api/contact` — were exposed without any rate limiting middleware, allowing attackers to exhaust server resources or spam an SMTP server with unlimited requests. The fix adds rate limiting to both endpoints, with stricter controls on the resource-intensive `/api/contact` route that triggers email sending operations. This change closes a directly exploitable denial-of-service vector in a production web service.

high

How Denial of Service via Specific Input Sequence happens in JavaScript (marked) and how to fix it

CVE-2026-41680 is a high-severity Denial of Service vulnerability in the marked Markdown parsing library, affecting versions prior to 18.0.2. By supplying a crafted input sequence to the parser, an attacker can cause the application to hang or exhaust resources, making the frontend unavailable. Upgrading marked from 18.0.0 to 18.0.2 in both `package.json` and `package-lock.json` closes the vulnerability without affecting valid Markdown rendering.

high

How Quadratic CPU Consumption happens in JavaScript YAML parsing and how to fix it

A high-severity denial-of-service vulnerability in js-yaml (GHSA-5p4m-2wfm-xmqj) caused quadratic CPU consumption when resolving `!!omap` YAML types in both the 3.x and 4.x branches. The fix upgrades js-yaml from 3.14.2 to 3.15.1 and from 4.1.1 to 4.3.1, eliminating the algorithmic complexity exploit while leaving all valid YAML inputs unaffected.

high

How Path Traversal happens in PostCSS Source Map Loading and how to fix it

A path traversal vulnerability in PostCSS versions before 8.5.18 allowed malicious `sourceMappingURL` comments in CSS files to trick PostCSS into loading arbitrary `.map` files from the filesystem. The fix upgrades PostCSS from 8.5.15 to 8.5.18 in `frontend/package-lock.json` and pins the version via an override in `frontend/package.json`, closing the file disclosure vector before it could be chained with other weaknesses.