Skip to content

GHSA-62hf-57xw-28j9 CVE-2026-42039

Axios: unbounded recursion in toFormData causes DoS via deeply nested request data

High npm
Severity
0.0 / 10
High · CVSS 4.0
Exploit chance (EPSS)
0.77%
Chance of exploitation in the next 30 days. Higher than 55.69% of scored vulnerabilities.
Known exploited
No
Not in CISA's catalog
Weakness
CWE-674 Uncontrolled Recursion
Fix
1.15.1
Upgrade axios to this version or later

Description

Summary

toFormData recursively walks nested objects with no depth limit, so a deeply nested value passed as request data crashes the Node.js process with a RangeError.

Details

lib/helpers/toFormData.js:210 defines an inner build(value, path) that recurses into every object/array child (line 225: build(el, path ? path.concat(key) : [key])). The only safeguard is a stack array used to detect circular references; there is no maximum depth and no try/catch around the recursion. Because build calls itself once per nesting level, a payload nested roughly 2000+ levels deep exhausts V8's call stack.

toFormData is the serializer behind FormData request bodies and AxiosURLSearchParams (used by buildURL when params is an object with URLSearchParams unavailable, see lib/helpers/buildURL.js:53 and lib/helpers/AxiosURLSearchParams.js:36). Any server-side code that forwards a client-supplied object into axios({ data, params }) therefore reaches the recursive walker with attacker-controlled depth.

The RangeError is thrown synchronously from inside forEach, escapes toFormData, and propagates out of the axios request call. In typical Express/Fastify request handlers this terminates the running request; in synchronous startup paths or worker threads it can crash the whole process.

PoC

import toFormData from 'axios/lib/helpers/toFormData.js';
import FormData from 'form-data';

function nest(depth) {
  let o = { leaf: 1 };
  for (let i = 0; i < depth; i++) o = { a: o };
  return o;
}

try {
  toFormData(nest(2500), new FormData());
} catch (e) {
  console.log(e.name + ': ' + e.message);
}
// RangeError: Maximum call stack size exceeded

Server-side reachability example:

// vulnerable proxy pattern
app.post('/forward', async (req, res) => {
  await axios.post('https://upstream/api', req.body); // req.body user-controlled
  res.send('ok');
});
// attacker POST /forward with {"a":{"a":{"a":... 2500 deep ...}}}
// -> toFormData build() overflows -> request handler crashes

Verified on axios 1.15.0 (latest, 2026-04-10), Node.js 20, 3/3 PoC runs reproduce the RangeError at depth 2500.

Impact

A remote, unauthenticated attacker who can influence an object passed to axios as request data or params triggers an uncaught RangeError inside the synchronous recursive walker. In server-side applications that proxy or re-send client JSON through axios this crashes the request handler and, in worker/cluster setups, the process. Fix by bounding recursion depth in toFormData's build function (reject or throw on depths beyond a configurable limit, e.g. 100) or rewriting the walker iteratively.

Affected versions

npm

PackageVulnerableFixed in
axios
>= 1.0.0, < 1.15.1
1.15.1
axios
< 0.31.1
0.31.1

How to fix

Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.

axios npm → 1.15.1

npm
npm install axios@1.15.1
yarn
yarn add axios@1.15.1
pnpm
pnpm add axios@1.15.1

Severity breakdown

CVSS 4.0 0.0

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Attack vector
Network
Attack complexity
Low
Attack requirements
None
Privileges required
None
User interaction
None
Confidentiality (vulnerable system)
None
Integrity (vulnerable system)
None
Availability (vulnerable system)
Low
Confidentiality (subsequent systems)
None
Integrity (subsequent systems)
None
Availability (subsequent systems)
None

CVSS 3.1 7.5

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

Weakness

CWE-674: Uncontrolled Recursion

The product does not properly control the amount of recursion that takes place, consuming excessive resources, such as allocated memory or the program stack.

How to prevent it
  • Implementation: Ensure that an end condition will be reached under all logic conditions. The end condition may include checking against the depth of recursion and exiting with an error if the recursion goes too deep. The complexity of the end condition contributes to the effectiveness of this action.
  • Implementation: Increase the stack size.

References

Advisories

Packages

Other links

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy it's related
GHSA-44g4-m2mj-wpvx
Axios: CIDR-form NO_PROXY entries are ignored, causing proxy exclusion bypass for internal IP ranges
Medium Also affects axios
GHSA-x97p-jq2g-jp4f
Axios: Prototype Pollution Gadget in axios toFormData Options
High Also affects axios
GHSA-vh66-26gq-q6x8
Axios: Prototype pollution gadget in fetch adapter can alter outbound requests
Medium Also affects axios
GHSA-r4gj-5m52-g5wh
Axios: maxRedirects: 0 is not enforced by the fetch adapter, allowing redirect-based SSRF
High Also affects axios
GHSA-mghh-pgcx-3jjj
Axios: ReDoS (O(N²)) in shouldBypassProxy host normalization, reachable via untrusted redirect Location
High Also affects axios
GHSA-m8m8-qj5v-23w3
Axios: Node HTTP adapter prototype-pollution gadget allows request socket hijack via inherited createConnection
High Also affects axios
GHSA-j8rh-479h-cp32
Axios: Header Injection via Inherited headers After Minimal Interceptor
Medium Also affects axios
GHSA-c29m-xwm3-cm6r
Axios: ReDoS in fromDataURI data: URL parser freezes the Node event loop (DoS)
High Also affects axios
Is this in your code?

MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.

Check your repos with MergeHarbor