Loading...
Skip to main content

CVE-2026-101908 — Axios: Prototype pollution gadget in axios — CVE...

MEDIUM

Axios: Prototype pollution gadget in fetch adapter can alter outbound requests

Published September 30, 2026Updated September 30, 2026Source: osv

Summary

## Summary 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. ## Impact 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 Functionality Affected: - `adapter: 'fetch'`. - Runtime environments where the fetch adapter is selected. - Requests where `fetchOptions` is an object that does not have safe own values for sensitive fetch init fields. Not affected: - Node HTTP adapter. - Requests that do not use the fetch adapter. - Processes where `Object.prototype` is not polluted. ## Technical Details `lib/adapters/fetch.js` builds: ```js 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`. ## Proof of Concept of Attack Constrained local demonstration: ```js 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. ## Workarounds 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. <details> <summary><h3>Original report</h3></summary> 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: ```js 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: ```json { "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: ```diff - _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. </details> ---

Advisory Timeline

  • First published September 30, 2026 (12 days ago).
  • Last revised September 30, 2026 — 0 days after initial publication.

Remediation

Upgrade to the fixed version using your package manager.

npm
Update axios to 1.20.0 or later
npm install axios@1.20.0

After upgrading, run your dependency scanner again to confirm the vulnerability is resolved.

Affected Packages (1)

Affects 1 ecosystem: npm (1).

PackageEcosystemAffectedFixed In
axios
npm
All versions1.20.0

Vulnerability Classification

Common Weakness Enumeration (CWE) identifiers for this vulnerability type.

  • CWE-1321
    Prototype PollutionMITRE

CVSS Score Breakdown

What the CVSS (Common Vulnerability Scoring System) 8.8 score means for each attack dimension.

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
—
Confidentiality
—
Integrity
—
Availability
—

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

Frequently Asked Questions

What is CVE-2026-101908?
Axios: Prototype pollution gadget in fetch adapter can alter outbound requests This vulnerability has been assigned a severity rating of MEDIUM (CVSS score: 8.8/10).
How do I check if my project is affected by CVE-2026-101908?
CVE-2026-101908 affects axios. Use GeekWala's free vulnerability scanner to check your dependencies against CVE-2026-101908 and 200,000+ other known vulnerabilities.

Severity & Exploitability

CVSS Score
8.8

High exploitability or significant impact. Prioritize remediation within days.

Also Known As

GHSA-vh66-26gq-q6x8

Related CVEs

Check if you're affected

Scan your dependencies to see if this vulnerability affects your projects.

Scan Your Dependencies