CVE-2026-67313: Axios Denial of Service Vulnerability
MODERATECVE-2026-67313 is a MODERATE denial of service vulnerability (CWE-400: Uncontrolled Resource Consumption) affecting Axios libraries in the npm ecosystem. The issue involves excessive recursion in formdatatojson can cause denial of service. Remediation is available by upgrading affected packages to version 0.33.0, 1.18.0.
CVE-2026-67313 at a Glance
How to Fix CVE-2026-67313
To remediate this vulnerability, upgrade all affected Axios dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install axios@0.33.0
npm install axios@1.18.0
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls axios
How to Check if You Are Affected
To determine whether your Node.js application is affected by CVE-2026-67313, inspect your project dependencies using npm:
npm ls axios
Analyze the terminal output to locate any version of Axios in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.33.0), your application is affected.
Note: The npm ls axios command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-400: Uncontrolled Resource Consumption, where the product does not properly control the allocation and maintenance of a limited resource. In Axios, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-67313 Affected Axios Versions
2 component(s)References
Frequently Asked Questions
What is CVE-2026-67313?
Which Axios versions are affected?
What version fixes CVE-2026-67313?
Is axios affected?
What CWE is associated with CVE-2026-67313?
How can I check npm dependencies for CVE-2026-67313?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-42h9-826w-cgv3",
"modified" : "2026-09-01T18:40:38Z",
"published" : "2026-07-20T17:58:59Z",
"aliases" : [ "CVE-2026-67313" ],
"summary" : "Axios: Excessive recursion in formDataToJSON can cause denial of service",
"details" : "## Summary\nAxios 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.\n\nApplications 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.\n\n## Impact\nThe impact is denial of service against applications that process untrusted `FormData` field names through axios' FormData-to-JSON conversion.\n\nThe 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.\n\nServer-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.\n\n## Affected Functionality\nAffected APIs and paths:\n- `axios.formToJSON(formData)`\n- `import { formToJSON } from \"axios\"`\n- `lib/helpers/formDataToJSON.js`\n- axios default `transformRequest` when `data` is `FormData` and `Content-Type` contains `application/json`\n\nUnaffected or lower-risk paths:\n- Normal multipart `FormData` requests without `JSON Content-Type`\n- `toFormData()` object-to-FormData serialisation, which already has a `maxDepth` guard\n- Axios versions before 0.28.0, where this helper and public API were not present\n\n## Technical Details\n`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.\n\n`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:\n\n`const result = buildPath(path, value, target[name], index);`\n\nA key containing thousands of bracket segments, therefore, creates thousands of recursive calls. At sufficient depth, V8 throws `RangeError: Maximum call stack size exceeded`.\n\nAxios 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.\n\n## Proof of Concept of Attack\n```js\nimport { formToJSON } from \"axios\";\n\nconst fd = new FormData();\nfd.append(\"a\" + \"[x]\".repeat(15000), \"value\");\n\ntry {\n formToJSON(fd);\n console.log(\"not vulnerable\");\n} catch (err) {\n console.log(`${err.constructor.name}: ${err.message}`);\n}\n```\n\nExpected vulnerable result:\n\nRangeError: Maximum call stack size exceeded\n\nThe axios request transform path can also be reached before network I/O:\n\n```js\nimport axios from \"axios\";\n\nconst fd = new FormData();\nfd.append(\"a\" + \"[x]\".repeat(15000), \"value\");\n\nawait axios\n .post(\"http://127.0.0.1:1/\", fd, {\n headers: { \"Content-Type\": \"application/json\" }\n })\n .catch((err) => console.log(`${err.constructor.name}: ${err.message}`));\n```\n\nExpected vulnerable result:\n\nRangeError: Maximum call stack size exceeded\n\n## Workarounds\nApplications can avoid the vulnerable path by not converting attacker-controlled `FormData` to JSON with axios.\n\nIf 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.\n\nFor axios requests carrying untrusted `FormData`, avoid setting `Content-Type: application/json`; leaving the data as multipart FormData bypasses `formDataToJSON()`.\n\nCatching 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.\n\n<details>\n<summary>Original Report</summary>\n# Axios SSRF via Incomplete Loopback Detection\n## 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\n\n---\n\n## 1. Classification\n\n| CWE | CVSS Score | Severity | Type |\n|-----|-----------|----------|------|\n| CWE-918 | 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L) | HIGH | Server-Side Request Forgery |\n\n## 2. Description\n\n### Summary\nThe `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.\n\n### Root Cause\n**File:** `lib/helpers/shouldBypassProxy.js`\n\n**`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.\n\n**`isIPv6Loopback` (lines 10-38):** Only checks `host === '::1'`. The `::` address (unspecified IPv6) also routes to the loopback, but is not recognised.\n\n**Attack Flow:**\n```\nisIPv4Loopback (line 3) — fails for 0.0.0.0\n → isLoopback (line 44) — wraps both checks, returns false\n → shouldBypassProxy (line 127) — PUBLIC API, exported default\n → lib/adapters/http.js (line 190) — Node.js HTTP adapter\n```\n\n### Attack Vector\n- **Access Vector:** Network (AV:N)\n- **Access Complexity:** Low (AC:L) — attacker only needs control of a URL\n- **Privileges Required:** None (PR:N)\n- **User Interaction:** None (UI:N)\n\n## 3. Proof of Concept\n\n### Phase 1: Logic Verification\n\n```javascript\nimport shouldBypassProxy from 'axios/lib/helpers/shouldBypassProxy.js';\n\n// Normal loopback — correctly returns true (bypasses proxy)\nshouldBypassProxy('http://127.0.0.1:9999/'); // → true\n\n// Vulnerable — returns false (goes through proxy!)\nshouldBypassProxy('http://0.0.0.0:9999/'); // → false ← SSRF\nshouldBypassProxy('http://[::]:9999/'); // → false ← SSRF\nshouldBypassProxy('http://[::ffff:0.0.0.0]:9999/'); // → false ← SSRF\n```\n\n### Phase 2: Docker E2E Reproduction\n\nA full 3-container Docker reproduction was created and tested:\n\n- **Proxy container:** Simple HTTP forward proxy on port 8888\n- **Internal container:** Internal service on port 9999 (simulates sensitive internal resource)\n- **Attacker container:** Runs the test script with Axios source mounted\n\n**Reproduction steps:**\n```bash\ncd /tmp/deep-e2e\ndocker compose up -d\ndocker compose exec attacker node test-ssrf.js\n```\n\n**Results:**\n- Test 1: `127.0.0.1 + NO_PROXY=localhost` → BYPASS (correct) \n- Test 2: `0.0.0.0 + NO_PROXY=localhost` → VIA_PROXY (SSRF) \n- Test 3: `[::] + NO_PROXY=localhost` → VIA_PROXY (SSRF) \n- Test 4: `[::ffff:0.0.0.0] + NO_PROXY=localhost` → VIA_PROXY (SSRF) \n\n### Phase 3: Actual Axios Client\n\nThe real Axios HTTP client (v1.16.1, source tree) was tested through proxy configuration:\n- Axios with `proxy: { host: 'proxy', port: 8888 }` \n- Setting `NO_PROXY=localhost` and requesting `http://0.0.0.0:9999/`\n- Result: Axios forwarded the request through the proxy instead of bypassing it\n\n## 4. Impact\n\n### Attack Scenario\n1. Attacker has control over a URL that an Axios client will request (direct input, redirect target, open redirect chain)\n2. The Axios client is configured with a proxy (e.g., corporate proxy) and `NO_PROXY=localhost` to protect internal services\n3. Attacker supplies `http://0.0.0.0:8080/admin` as the target URL\n4. Axios sends the request through the proxy\n5. The proxy resolves `0.0.0.0` → the proxy's own loopback → reaches the internal admin service on port 8080\n\n### Potential Consequences\n- **Information disclosure (C:L):** Internal service responses become accessible\n- **Integrity impact (I:L):** Attacker can trigger actions on internal services (if proxy supports PUT/POST/DELETE)\n- **Availability impact (A:L):** Limited — depends on internal service behavior\n\n### Likelihood\n- **High** — proxy bypass is a common pattern in microservice architectures\n- **Medium** — requires attacker control of a URL (not always available)\n\n## 5. Remediation\n\n### Code Fix\n\n**File:** `lib/helpers/shouldBypassProxy.js`\n\n```javascript\nfunction isIPv4Loopback(host) {\n if (host === '0.0.0.0') return true; // ADD THIS LINE\n const parts = host.split('.');\n if (parts.length !== 4) return false;\n if (parts[0] !== '127') return false;\n return parts.every(p => /^\\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);\n}\n\nfunction isIPv6Loopback(host) {\n if (host === '::1' || host === '::') return true; // ADD '::'\n // ... rest of implementation\n}\n```\n\n### Workarounds\n- Add `0.0.0.0` and `::` to the `NO_PROXY` environment variable explicitly\n- Use `127.0.0.1` instead of `0.0.0.0` in all internal service URLs\n- Implement URL validation to reject `0.0.0.0` and `::` before passing to Axios",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "axios"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0.28.0"
}, {
"fixed" : "0.33.0"
} ]
} ]
}, {
"package" : {
"ecosystem" : "npm",
"name" : "axios"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "1.0.0"
}, {
"fixed" : "1.18.0"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/axios/axios/security/advisories/GHSA-42h9-826w-cgv3"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-67313"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-68942"
}, {
"type" : "WEB",
"url" : "https://github.com/axios/axios/pull/11000"
}, {
"type" : "WEB",
"url" : "https://github.com/axios/axios/pull/11001"
}, {
"type" : "WEB",
"url" : "https://github.com/axios/axios/commit/1417285c69344bbcc6420a021f67dee0c6fedb2d"
}, {
"type" : "WEB",
"url" : "https://github.com/axios/axios/commit/32fc489632377d214db55bfa4e2c48486a7d7ce2"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/axios/axios"
}, {
"type" : "WEB",
"url" : "https://github.com/axios/axios/releases/tag/v0.33.0"
}, {
"type" : "WEB",
"url" : "https://github.com/axios/axios/releases/tag/v1.18.0"
}, {
"type" : "WEB",
"url" : "https://www.vulncheck.com/advisories/axios-before-denial-of-service-via-formdatatojson"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-400", "CWE-674" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-07-20T17:58:59Z",
"nvd_published_at" : "2026-08-06T22:18:25Z"
}
}