AXIOS · CVE-2026-101908 · Package
FIX → 1.20.0 · >=1.20.0
When the Axios fetch adapter runs, inherited properties on fetchOptions can override the request headers, so a process already affected by prototype pollution can make Axios send attacker-chosen headers such as Authorization while dropping the caller's headers. Axios does not create the pollution itself; it is a gadget that needs a separate prototype-pollution flaw first.
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 applications that use Axios with the fetch adapter (adapter: 'fetch') on a runtime where fetch passes headers from fetchOptions, such as Node's undici-backed fetch, and where the process can also be polluted through another prototype-pollution flaw. The Node HTTP adapter is not affected, and processes where Object.prototype is not polluted are not exposed.
Not affected if axios-below-1.7.0, no-fetch-adapter, no-prototype-pollution, node-http-adapter
Who cares axios, fetch-adapter, node, npm
npm ls axios; affected versions are >= 1.7.0, < 1.20.0.adapter: 'fetch' or a fetchOptions option passed to Axios requests.Object.prototype (prototype pollution sources such as unsafe deep merge libraries).Axios fetch adapter requests can be altered by inherited properties on fetchOptions. The adapter resolves method, headers, body, signal, and credentials into resolvedOptions, creates a Request, and then calls fetch(request, fetchOptions) instead of fetch(request, resolvedOptions). In runtimes such as Node's undici-backed fetch, inherited fetchOptions.headers can override the headers already placed on the Request.
Axios does not create the prototype pollution source. This is a read-side gadget that becomes exploitable after same-process prototype pollution.
An attacker with a prior prototype-pollution primitive can cause affected fetch-adapter requests to send attacker-controlled headers and drop caller-specified headers. This can affect authorization, cache behavior, metadata-service interactions, or application-specific header-based controls.
The issue is specific to fetch-adapter behavior and does not affect Node HTTP adapter requests.
Affected:
adapter: 'fetch'.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 later.fetchOptions is an object that does not have safe own values for sensitive fetch init fields.Not affected:
Object.prototype is not polluted.lib/adapters/fetch.js builds:
const resolvedOptions = {
...fetchOptions,
signal: composedSignal,
method: method.toUpperCase(),
headers: toByteStringHeaderObject(headers.normalize()),
body: data,
duplex: 'half',
credentials: isCredentialsSupported ? withCredentials : undefined,
};
request = isRequestSupported && new Request(url, resolvedOptions);
let response = await (isRequestSupported
? _fetch(request, fetchOptions)
: _fetch(url, resolvedOptions));
The fallback path without Request uses resolvedOptions, but the Request path passes the original fetchOptions as the second argument to fetch(). That second argument can contain inherited properties from Object.prototype.
Local verification on axios 1.18.1 set Object.prototype.headers = { Authorization: 'Bearer POLLUTED' } and called the fetch adapter with headers: { 'X-Good': 'yes' }, fetchOptions: {}. The loopback server received Authorization: Bearer POLLUTED and did not receive X-Good.
Constrained local demonstration:
Object.prototype.headers = { Authorization: 'Bearer POLLUTED' };
try {
await axios.get(url, {
adapter: 'fetch',
headers: { 'X-Good': 'yes' },
fetchOptions: {}
});
} finally {
delete Object.prototype.headers;
}
Expected safe behavior is that the sanitized axios headers remain in force. Current behavior can use the inherited fetch init headers instead.
Use the Node HTTP adapter for security-sensitive server-side requests until fixed. If the fetch adapter must be used, avoid passing empty fetchOptions objects in processes where prototype pollution is possible, and set explicit safe own values for fetch init fields.
Hello, I’m not completely sure if this is something you’d consider a security issue, since it depends on prototype pollution happening somewhere else first, but I wanted to report it just in case.
I was testing the fetch adapter with polluted prototype values and found that Object.prototype.headers can change the request axios sends.
The issue seems to be in lib/adapters/fetch.js. Axios creates a Request with the resolved headers/method/body, but then sends it with fetch(request, fetchOptions). With undici, if fetchOptions doesn’t have its own headers, an inherited Object.prototype.headers value can be used during the final fetch call.
I tested it with this:
import http from 'node:http';
import axios from 'axios';
const server = http.createServer((req, res) => {
res.end(JSON.stringify({
authorization: req.headers.authorization || null,
xGood: req.headers['x-good'] || null
}));
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const { port } = server.address();
Object.prototype.headers = {
Authorization: 'Bearer POLLUTED'
};
try {
const res = await axios.get(`http://127.0.0.1:${port}/`, {
adapter: 'fetch',
headers: { 'X-Good': 'yes' },
fetchOptions: {}
});
console.log(res.data);
} finally {
delete Object.prototype.headers;
server.close();
}
The result I get is:
{
"authorization": "Bearer POLLUTED",
"xGood": null
}
So the polluted Authorization header is sent, and the normal axios header is not.
Changing the fetch call to pass the already resolved options fixes it for me:
- _fetch(request, fetchOptions)
+ _fetch(request, resolvedOptions)
resolvedOptions already includes ...fetchOptions, so custom fetch options should still work, while headers, method, body, and signal stay as clean own values.
This page as .md · .json · CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:H/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.