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
•Technically reviewed by Anupam Mediratta•Published August 26, 2026•Reviewed 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

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.


Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #3

Related Articles

critical

CVE-2026-59873: node-tar 7.5.11 DoS via Crafted Gzip Bomb

node-tar versions 7.5.11 through 7.5.18 are vulnerable to a denial-of-service attack through maliciously crafted gzip archives that decompress to disproportionately large sizes. An attacker can exploit this to exhaust memory and CPU resources by submitting a small, highly compressed archive that expands beyond configured limits during extraction.

high

MapManager.get() Race Condition Duplicates API Requests

The MapManager's `get(mapUid, cache)` method used a check-then-act pattern that permitted multiple concurrent requests to pass the cache miss check simultaneously, triggering redundant API calls and risking cache corruption. The fix introduces a `_pending` promise map to deduplicate in-flight fetches for identical map UIDs.

critical

Lampa Desktop Auto-Update Heuristic Bypass: Execution of Unverified

Lampa Desktop's auto-update mechanism downloaded JavaScript and CSS from `raw.githubusercontent.com` using only heuristic validation—file size thresholds and string pattern matching—that attackers could trivially satisfy. The fix introduces cryptographic integrity verification by cross-referencing Git blob hashes from the GitHub Contents API, ensuring downloaded code matches the repository's authoritative state before execution.

high

adm-zip 0.6.0 Preserves SUID Bits From ZIPs: CVE-2026-102282

The `adm-zip` dependency resolved to 0.6.0 in this project's dependency tree, a version affected by CVE-2026-102282: during extraction it applies the Unix permission bits stored in each ZIP entry's external file attributes verbatim, including the setuid (`04000`), setgid (`02000`), and sticky bits. An attacker who controls an archive passed to `extractAllTo()` or `extractEntryTo()` can therefore have the extractor create a setuid binary owned by whatever user the extraction process runs as. The

high

requestInput() Type Confusion: NaN and Object Bypass in JavaScript

The `requestInput()` utility function lacked validation on its `type` parameter and failed to handle `NaN` results from float conversions, creating a type confusion weakness. An attacker could supply malformed inputs that propagate unhandled `NaN` values or unexpected object types through the type system. The fix adds explicit guards against `NaN` type parameters and rejects non-primitive type values.

critical

No Rate Limit on /api/uploads/presign Enables DoS

The `/api/uploads/presign` endpoint accepted unlimited concurrent requests to generate storage presigned URLs, giving an attacker a free lever to exhaust storage-provider quotas and server resources. The fix adds an `express-rate-limit` middleware capping each client to 30 requests per minute on that route.