Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm
Not in CISA KEV

GHSA-42h9-826w-cgv3

Fix: axios/axios#11000

GHSA-42h9-826w-cgv3 is a Uncontrolled Resource Consumption vulnerability in axios. O3 Security confirms whether GHSA-42h9-826w-cgv3 is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Axios: Excessive recursion in formDataToJSON can cause denial of service

Also known asCVE-2026-67313
Published
Jul 20, 2026
Updated
Sep 3, 2026
Affected
2 pkgs
Patched
2 / 2
Exploits
None indexed
Exploitation data as of Sep 7, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for GHSA-42h9-826w-cgv3.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs36th percentile — riskier than 36% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Real-World Exposure

2 pkgs affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

179Kother npm packages depend on this — each one inherits the vulnerability until it's patched upstream
axiosnpm
106.5Mdownloads / week

Description

Summary

Axios versions 0.28.0 and later contain uncontrolled recursion in formDataToJSON, the helper behind the public axios.formToJSON() / named formToJSON API and the default request transform used when FormData is sent with an application/json content type.

Applications are affected when they pass attacker-controlled FormData field names into this functionality. A field name with thousands of nested bracket segments can exhaust the JavaScript call stack and throw RangeError: Maximum call stack size exceeded, causing request failure and, in applications that do not handle the exception or rejected promise, possible process termination.

Impact

The impact is denial of service against applications that process untrusted FormData field names through axios' FormData-to-JSON conversion.

The vulnerable path is not reached by merely installing axios, by normal multipart FormData pass-through, or by ordinary axios requests that do not request JSON serialisation of FormData. In the default axios request, the error is produced before network I/O and returned as a rejected Promise. Direct use of formToJSON() throws synchronously.

Server-side applications are the primary risk when remote users can submit arbitrary form field names, and the application converts those fields with formToJSON() or sends them through axios as JSON.

Affected Functionality

Affected APIs and paths:

  • axios.formToJSON(formData)
  • import { formToJSON } from "axios"
  • lib/helpers/formDataToJSON.js
  • axios default transformRequest when data is FormData and Content-Type contains application/json

Unaffected or lower-risk paths:

  • Normal multipart FormData requests without JSON Content-Type
  • toFormData() object-to-FormData serialisation, which already has a maxDepth guard
  • Axios versions before 0.28.0, where this helper and public API were not present

Technical Details

lib/helpers/formDataToJSON.js parses a form field name into path segments with parsePropPath(). For a key such as a[x][x][x], each bracketed segment becomes another path element.

formDataToJSON() then calls the nested buildPath(path, value, target, index) function. buildPath() recursively calls itself once for each path segment and does not enforce a maximum depth:

const result = buildPath(path, value, target[name], index);

A key containing thousands of bracket segments, therefore, creates thousands of recursive calls. At sufficient depth, V8 throws RangeError: Maximum call stack size exceeded.

Axios already applies a depth guard to the inverse serializer in lib/helpers/toFormData.js, where maxDepth defaults to 100 and exceeding it throws AxiosError with code ERR_FORM_DATA_DEPTH_EXCEEDED. formDataToJSON() does not currently have equivalent protection.

Proof of Concept of Attack

import { formToJSON } from "axios";

const fd = new FormData();
fd.append("a" + "[x]".repeat(15000), "value");

try {
  formToJSON(fd);
  console.log("not vulnerable");
} catch (err) {
  console.log(`${err.constructor.name}: ${err.message}`);
}

Expected vulnerable result:

RangeError: Maximum call stack size exceeded

The axios request transform path can also be reached before network I/O:

import axios from "axios";

const fd = new FormData();
fd.append("a" + "[x]".repeat(15000), "value");

await axios
  .post("http://127.0.0.1:1/", fd, {
    headers: { "Content-Type": "application/json" }
  })
  .catch((err) => console.log(`${err.constructor.name}: ${err.message}`));

Expected vulnerable result:

RangeError: Maximum call stack size exceeded

Workarounds

Applications can avoid the vulnerable path by not converting attacker-controlled FormData to JSON with axios.

If conversion is required before a fixed axios release is available, validate FormData field names before calling formToJSON() or before sending FormData with Content-Type: application/json. Reject keys whose parsed nesting depth exceeds the application's expected schema.

For axios requests carrying untrusted FormData, avoid setting Content-Type: application/json; leaving the data as multipart FormData bypasses formDataToJSON().

Catching the resulting error can prevent process termination, but it does not remove the uncontrolled-recursion behaviour and should not be treated as the primary mitigation.

<details> <summary>Original Report</summary> # Axios SSRF via Incomplete Loopback Detection ## CWE-918 | CVSS 7.5 (HIGH) | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L

1. Classification

CWECVSS ScoreSeverityType
CWE-9187.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L)HIGHServer-Side Request Forgery

2. Description

Summary

The shouldBypassProxy() function in Axios fails to recognise 0.0.0.0, ::, and ::ffff:0.0.0.0 as loopback addresses. When NO_PROXY=localhost is configured, requests to these addresses are incorrectly forwarded through the proxy instead of being sent directly, enabling an SSRF attack against internal services reachable via the proxy's loopback interface.

Root Cause

File: lib/helpers/shouldBypassProxy.js

isIPv4Loopback (lines 3-8): Only checks for 127.x.x.x addresses by inspecting parts[0] !== '127'. The 0.0.0.0 address has parts[0] === '0', so it falls through as non-loopback, even though on Linux 0.0.0.0 routes to the loopback interface.

isIPv6Loopback (lines 10-38): Only checks host === '::1'. The :: address (unspecified IPv6) also routes to the loopback, but is not recognised.

Attack Flow:

isIPv4Loopback (line 3) — fails for 0.0.0.0
  → isLoopback (line 44) — wraps both checks, returns false
    → shouldBypassProxy (line 127) — PUBLIC API, exported default
      → lib/adapters/http.js (line 190) — Node.js HTTP adapter

Attack Vector

  • Access Vector: Network (AV:N)
  • Access Complexity: Low (AC:L) — attacker only needs control of a URL
  • Privileges Required: None (PR:N)
  • User Interaction: None (UI:N)

3. Proof of Concept

Phase 1: Logic Verification

import shouldBypassProxy from 'axios/lib/helpers/shouldBypassProxy.js';

// Normal loopback — correctly returns true (bypasses proxy)
shouldBypassProxy('http://127.0.0.1:9999/');  // → true

// Vulnerable — returns false (goes through proxy!)
shouldBypassProxy('http://0.0.0.0:9999/');    // → false  ← SSRF
shouldBypassProxy('http://[::]:9999/');        // → false  ← SSRF
shouldBypassProxy('http://[::ffff:0.0.0.0]:9999/'); // → false ← SSRF

Phase 2: Docker E2E Reproduction

A full 3-container Docker reproduction was created and tested:

  • Proxy container: Simple HTTP forward proxy on port 8888
  • Internal container: Internal service on port 9999 (simulates sensitive internal resource)
  • Attacker container: Runs the test script with Axios source mounted

Reproduction steps:

cd /tmp/deep-e2e
docker compose up -d
docker compose exec attacker node test-ssrf.js

Results:

  • Test 1: 127.0.0.1 + NO_PROXY=localhost → BYPASS (correct)
  • Test 2: 0.0.0.0 + NO_PROXY=localhost → VIA_PROXY (SSRF)
  • Test 3: [::] + NO_PROXY=localhost → VIA_PROXY (SSRF)
  • Test 4: [::ffff:0.0.0.0] + NO_PROXY=localhost → VIA_PROXY (SSRF)

Phase 3: Actual Axios Client

The real Axios HTTP client (v1.16.1, source tree) was tested through proxy configuration:

  • Axios with proxy: { host: 'proxy', port: 8888 }
  • Setting NO_PROXY=localhost and requesting http://0.0.0.0:9999/
  • Result: Axios forwarded the request through the proxy instead of bypassing it

4. Impact

Attack Scenario

  1. Attacker has control over a URL that an Axios client will request (direct input, redirect target, open redirect chain)
  2. The Axios client is configured with a proxy (e.g., corporate proxy) and NO_PROXY=localhost to protect internal services
  3. Attacker supplies http://0.0.0.0:8080/admin as the target URL
  4. Axios sends the request through the proxy
  5. The proxy resolves 0.0.0.0 → the proxy's own loopback → reaches the internal admin service on port 8080

Potential Consequences

  • Information disclosure (C:L): Internal service responses become accessible
  • Integrity impact (I:L): Attacker can trigger actions on internal services (if proxy supports PUT/POST/DELETE)
  • Availability impact (A:L): Limited — depends on internal service behavior

Likelihood

  • High — proxy bypass is a common pattern in microservice architectures
  • Medium — requires attacker control of a URL (not always available)

5. Remediation

Code Fix

File: lib/helpers/shouldBypassProxy.js

function isIPv4Loopback(host) {
  if (host === '0.0.0.0') return true;  // ADD THIS LINE
  const parts = host.split('.');
  if (parts.length !== 4) return false;
  if (parts[0] !== '127') return false;
  return parts.every(p => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
}

function isIPv6Loopback(host) {
  if (host === '::1' || host === '::') return true;  // ADD '::'
  // ... rest of implementation
}

Workarounds

  • Add 0.0.0.0 and :: to the NO_PROXY environment variable explicitly
  • Use 127.0.0.1 instead of 0.0.0.0 in all internal service URLs
  • Implement URL validation to reject 0.0.0.0 and :: before passing to Axios

Affected Packages

2 total 2 fixed
EcosystemPackageVulnerable rangeFix
📦npmaxios0.28.0&&< 0.33.00.33.0
📦npmaxios1.0.0&&< 1.18.01.18.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for axios. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update axios to 0.33.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-42h9-826w-cgv3 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-42h9-826w-cgv3 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-42h9-826w-cgv3. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Frequently Asked Questions

## Summary Axios versions `0.28.0` and later contain uncontrolled recursion in `formDataToJSON`, the helper behind the public `axios.formToJSON()` / named `formToJSON` API and the default request transform used when FormData is sent with an `application/json` content type. Applications are affected when they pass attacker-controlled `FormData` field names into this functionality. A field name with thousands of nested bracket segments can exhaust the JavaScript call stack and throw `RangeError: Maximum call stack size exceeded`, causing request failure and, in applications that do not handle t
O3 Security · Impact-Aware SCA

Is GHSA-42h9-826w-cgv3 in your dependencies?

O3 detects GHSA-42h9-826w-cgv3 across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.

GHSA-42h9-826w-cgv3: axios Server-Side… | O3 Security