CVE-2026-67317
Executive Summary
CVE-2026-67317 affects the widely used JavaScript HTTP client axios (NPM package). Versions from 1.7.0 up to, but not including, 1.18.0 fail to enforce the maxBodyLength configuration option when a WHATWG ReadableStream is used as the request body in the fetch adapter, and when Content-Length cannot be determined from the stream. An attacker who controls or manipulates the request body (e.g., via multipart upload, streaming data, or a malicious web page in a browser-like environment) can bypass upload size limits, leading to uncontrolled network egress and resource exhaustion on the client and target server.
This vulnerability is particularly dangerous in supply chain scenarios: axios is a dependency in hundreds of thousands of Node.js applications and SaaS backend services. Organizations using vulnerable axios versions are exposed to DoS and infrastructure abuse, especially when accepting untrusted streaming uploads.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
- Ecosystem: NPM (
axiospackage) - Affected Range:
>=1.7.0<1.18.0 - Patch Version:
1.18.0 - Transitive Exposure: Applications pinning axios versions in
package-lock.jsonare at risk. Attackers can target any service that uses axios withmaxBodyLengthset but does not enforce it for stream bodies. - Recommendation: Audit all package lockfiles for vulnerable versions immediately. Use
npm auditwith the latest security registry data, and prioritize upgrading to1.18.0or later.
CVSS Breakdown & Threat Level
No official CVSS vector has been assigned (the NVD score is currently 0.0 due to incomplete analysis). Based on the disclosed mechanism, an estimated vector reflecting the impact would be:
CVE: CVE-2026-67317
CVSS:3.1 (estimated): AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
This places the vulnerability at High severity on the availability axis: an unauthenticated, network-adjacent attacker can cause resource exhaustion and uncontrolled network egress without requiring user interaction. Although no confidentiality or integrity impact is direct, the bypass of security controls (maxBodyLength) increases the attack surface.
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Availability Impact: High
Deep Dive & Mechanics
The axios fetch adapter normalizes request bodies and enforces maxBodyLength when Content-Length exists. For standard string, ArrayBuffer, URLSearchParams, and FormData, the exact byte length is known and a pre-flight check is trivial.
The flaw is in how the adapter processes WHATWG ReadableStream bodies. When a ReadableStream is passed as the request body, the total byte length is often unknown unless the stream is consumed. The vulnerable code checks Content-Length header or checks body.size only if it is a known numeric property. A ReadableStream has no .size property, so the check is skipped entirely.
Attackers can craft a request body that is an infinite or extremely large ReadableStream (e.g., generated on-the-fly) and send it through axios. The adapter forwards the stream directly, never measuring the actual bytes. The maxBodyLength security boundary is therefore bypassed, causing:
- Uncontrolled network egress: The attacker can make the server send endless data to a target, facilitating bandwidth exhaustion.
- Resource exhaustion: On the ingress side, the receiving server may try to buffer the entire stream, exhausting memory or disk.
The vulnerability is especially impactful in serverless functions and Node.js backends that rely on axios for proxying, file uploads, or streaming integrations.
Vulnerable vs. Patched Code
Vulnerable Code (axios 1.7.x to 1.17.x)
In lib/adapters/fetch.js, the pre-check logically resembles:
async function fetchAdapter(config) {
...
const requestBody = config.data;
// Vulnerable check: only validates if size is a number or Content-Length exists
if (utils.isFormData(requestBody)) {
// FormData has known size
} else if (requestBody && requestBody.size !== undefined) {
// string / ArrayBuffer / URLSearchParams have .size, .byteLength, etc.
}
// No else-if for ReadableStream: falls through without any check.
if (config.maxBodyLength && bodyLength > config.maxBodyLength) {
throw new AxiosError('Request body larger than maxBodyLength', ...);
}
...
}
Since requestBody.size is undefined for ReadableStream, the bodyLength variable remains unset, and the maxBodyLength check is skipped.
Patched Code (axios 1.18.0)
The patched version adds an async stream-length estimation or a stream branching approach:
// Pseudo-patched implementation
if (requestBody instanceof ReadableStream) {
try {
// Use a tee to count bytes or check Content-Length from the stream
const [countingStream, actualStream] = requestBody.tee();
const reader = countingStream.getReader();
let measuredLength = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
measuredLength += value.length;
}
if (config.maxBodyLength && measuredLength > config.maxBodyLength) {
throw new AxiosError('Request body larger than maxBodyLength', ...);
}
// Use actualStream for the request to avoid consuming it prematurely
config.data = actualStream;
} catch (err) {
// handle or rethrow
}
}
The key principle is that axios now proactively measures the stream length (with careful handling of backpressure) before dispatch, or aborts the request once the limit is exceeded during streaming.
Exploitation & Lab Setup
While no public exploit exists yet (POC_STATUS: None), the vulnerability can be triggered with a simple Node.js script that uses the unsupported stream body.
Red Team
Objective: Demonstrate bypass of maxBodyLength and cause resource exhaustion in a controlled lab.
- Install vulnerable axios:
npm install axios@1.17.0 - Create an endless ReadableStream and attempt to POST it to a local test server:
const axios = require('axios');
const { ReadableStream } = require('stream/web');
// Endless stream; first chunk sends a leading marker, then infinite data
const endlessStream = new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([1,2,3,4]));
// Simulate endless chunking
setInterval(() => {
controller.enqueue(new Uint8Array(1024 * 1024)); // 1 MB chunks
}, 10);
}
});
axios.post('http://localhost:3000/upload', endlessStream, {
maxBodyLength: 1024, // 1KB limit
headers: { 'Content-Type': 'application/octet-stream' }
}).catch((err) => {
console.log('Request failed as expected?', err.message);
});
On the target server, monitor memory and network usage to visualize the uncontrolled egress.
- For a more practical red-team scenario, use a slowly-feeding stream that under normal conditions would be legitimate, but once the limit is bypassed, it keeps sending data.
Blue Team
- Identify all applications using axios and their pinned versions. Use a script to scan
package-lock.json:
npm audit --json | jq '.metadata.vulnerabilities'
- Set up network policies and egress filtering to cap per-connection data transfer, regardless of application-level size limits.
- Monitor for unusually large HTTP payloads with
Transfer-Encoding: chunkedand noContent-Lengthheader. - In development, add an internal middleware that verifies the request body size on the receiving server side (defense in depth).
Indicators of Compromise (IOCs)
No specific malware family is associated with this CVE, but the following behavioral indicators suggest exploitation or probing:
Network IOCs:
- A very large number of HTTP requests where
Content-Length: 0or missing, paired withTransfer-Encoding: chunked. - Sustained outbound bandwidth from a Node.js process far exceeding the expected application baseline.
- Connections to untrusted destinations that last longer than the configured timeout, with rapidly increasing data volumes.
- A very large number of HTTP requests where
Host IOCs:
- Node.js processes showing abnormally high memory consumption (heap growth) due to buffering of an unbounded stream.
- Log entries from axios errors like
"Request body larger than maxBodyLength"appearing for streams where previously they never did (post-upgrade), or an absence of these errors for oversized requests in vulnerable versions. - Package manifest mismatches:
axiosversion inpackage.jsonis in the vulnerable range, yet no size errors are logged.
Detection Engineering
YARA Rule
Detect vulnerable axios version strings in NPM dependencies (package-lock.json or node_modules/axios/package.json):
rule Detect_Axios_Vulnerable_CVE_2026_67317 {
meta:
author = "Valters IT"
description = "Detects axios version strings that are vulnerable to CVE-2026-67317"
date = "2026-04-01"
reference = "CVE-2026-67317"
severity = "high"
strings:
$v1 = "\"axios\":\"1\\.7\\." ascii
$v2 = "\"axios\":\"1\\.8\\." ascii
$v3 = "\"axios\":\"1\\.9\\." ascii
$v4 = "\"axios\":\"1\\.1[0-7]\\." ascii
$pkg = "axios" ascii
condition:
$pkg and any of ($v*) and not ("\"axios\":\"1\\.18\\." ascii)
}
Sigma Rule
Detect excessive outbound traffic from a Node.js process. This rule focuses on Event ID 3 (network connection) in Windows, combined with a high number of distinct destinations or high-volume transfers:
title: Axios CVE-2026-67317 - Excessive Outbound Network Activity
status: experimental
description: Detects network connections initiated by Node.js processes that may indicate resource exhaustion caused by uncontrolled stream uploads (CVE-2026-67317).
logsource:
product: windows
category: network_connection
detection:
selection:
Image|endswith: node.exe
Protocol: tcp
condition: selection
timeframe: 5m
# This rule would be tuned with a baseline, e.g., 1000 unique destination IPs or >1GB egress.
# The detection engine should compute the sum of bytes sent in the timeframe.
# For a real deployment, add a threshold condition using an Enterprise rule or correlate with netflow data.
fields:
- DestinationIp
- Image
- User
falsepositives:
- Development machines performing large legitimate downloads
- Backup or sync applications using Node.js
level: high
Suricata Rule
Detect HTTP requests without a Content-Length header but with unexpected body size — a strong indicator of stream-body bypass attempts:
alert http any any -> $HOME_NET any (msg:"Possible Axios CVE-2026-67317 - Stream Body Without Content-Length"; flow:to_server,established; http.method; content:"POST"; http.header_names; content:"!Content-Length"; http.header_names; content:"|0d 0a|"; http.request_body; size:>1000000; sid:202667317; rev:1;)
Note: Suricata requires the http.request_body keyword to inspect body data. The absence of Content-Length is checked by testing that the header names list does not contain Content-Length. Since Suricata stateful matching may have limitations, a more robust approach is to use a Lua script or export to an external decoder. The rule above is a starting heuristic.
Nuclei Template
No public Nuclei template is provided. The report honors that requirement.
Remediation & Mitigation
Immediate Actions
Upgrade axios to
1.18.0or newer:npm install axios@^1.18.0Note: the fix may require introducing a breaking change if your code relies on undocumented
ReadableStreambehavior.Patch management: If an immediate upgrade is not possible, apply a temporary shim that overrides
maxBodyLengthvalidation using a wrapper:
const axios = require('axios');
const { ReadableStream } = require('stream/web');
const originalPost = axios.post;
axios.post = function(url, data, config = {}) {
if (data && typeof data.getReader === 'function') { // ReadableStream
// Stream length validation (pseudo-code)
// This should be done in a production-safe way, e.g., using a TransformStream to count bytes and abort on exceed.
if (config.maxBodyLength) {
// If you can't measure the whole stream, at least enforce via a counter upon each read.
return wrappedStreamWithLimit(data, config.maxBodyLength);
}
}
return originalPost.call(this, url, data, config);
};
- Use a reverse proxy or API gateway to enforce a maximum request body size at the transport layer (e.g.,
client_max_body_sizein nginx, but note this is not a WordPress-specific fix).
Long-term Controls
- Network egress filtering: Implement per-process or per-pod network limits in Kubernetes/cloud environments, so even a compromised axios instance cannot send excessive data.
- Endpoint monitoring: Set up alerting on total bytes sent per Node.js process/container.
- Input validation: Do not accept raw
ReadableStreambodies from untrusted endpoints without an explicit size pre-check. - Container hardening: Run Node.js applications with read-only root filesystem and strict resource quotas (CPU/memory) to mitigate resource exhaustion.
Detection Post-Patch
After upgrading, verify that your current integration tests still pass. Add a regression test for maxBodyLength enforcement with a ReadableStream:
test('maxBodyLength is enforced for ReadableStream', async () => {
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array(4096));
controller.close();
}
});
await expect(
axios.post('http://example.com', stream, { maxBodyLength: 1024 })
).rejects.toThrow('Request body larger than maxBodyLength');
});
Indicators of Compromise (IOCs) Recap
- Missing
Content-Lengthin POST/PUT requests with large response bodies. - Node.js process network egress > 10x baseline.
- HTTP responses with status 431 (Request Header Fields Too Large) or 413 (Content Too Large) when the server is configured to reject, but these are absent from logs on a vulnerable client.
- NPM lockfile contains a version
>=1.7.0 <1.18.0.
Valters IT
This report was prepared by the Valters IT DevSecOps Threat Intelligence Team. All detection rules are provided under MIT license – test in your environment before production use.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.