{"id":"CVE-2026-101908","aliases":["CLSA-2026-1790854830","CLSA-2026-1791667309","CLSA-2026-1792190983","CLSA-2026-1792429081","CLSA-2026-1792429317","CLSA-2026-1792488905","CLSA-2026-1793099904","CLSA-2026-1793101849","CLSA-2026-1793109367","CLSA-2026-1793110604","DEBIAN-CVE-2026-101908","EUVD-2026-88387","GHSA-vh66-26gq-q6x8","RHSA-2026:74869","RHSA-2026:74871","RHSA-2026:74872","UBUNTU-CVE-2026-101908"],"status":"published","title":"Axios: Prototype pollution gadget in fetch adapter can alter outbound requests","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","severity":{"version":"4.0","score":6.9,"vector":"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","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00471,"percentile":0.40975,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-1321"],"published":"2026-09-28T17:38:55Z","modified":"2026-10-28T02:31:08Z","fixes":[{"ecosystem":"npm","package":"axios","fixed_in":["1.20.0"],"sources":["ghsa","osv"]},{"ecosystem":"Debian:14","package":"node-axios","fixed_in":["1.20.0-1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.7.0"},{"fixed":"1.20.0"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.18.1-tuxcare.0"},{"fixed":"1.18.1-tuxcare.1"}]}],"versions":["1.18.1"],"bundled":10},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.16.0-tuxcare.0"},{"fixed":"1.16.0-tuxcare.2"}]}],"versions":["1.16.0","1.16.0-tuxcare.1"],"bundled":6},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.13.5-tuxcare.0"},{"fixed":"1.13.5-tuxcare.2"}]}],"versions":["1.13.5","1.13.5-tuxcare.1"],"bundled":6},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.17.0-tuxcare.0"},{"fixed":"1.17.0-tuxcare.3"}]}],"versions":["1.17.0","1.17.0-tuxcare.1","1.17.0-tuxcare.2"],"bundled":12},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.18.0-tuxcare.0"},{"fixed":"1.18.0-tuxcare.2"}]}],"versions":["1.18.0","1.18.0-tuxcare.1"],"bundled":11},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.19.0-tuxcare.0"},{"fixed":"1.19.0-tuxcare.1"}]}],"versions":["1.19.0"],"bundled":12},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.16.1-tuxcare.0"},{"fixed":"1.16.1-tuxcare.3"}]}],"versions":["1.16.1","1.16.1-tuxcare.1","1.16.1-tuxcare.2"],"bundled":4},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.13.2-tuxcare.0"},{"fixed":"1.13.2-tuxcare.2"}]}],"versions":["1.13.2","1.13.2-tuxcare.1"],"bundled":32},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.13.6-tuxcare.0"},{"fixed":"1.13.6-tuxcare.1"}]}],"versions":["1.13.6"],"bundled":6},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.12.2-tuxcare.0"},{"fixed":"1.12.2-tuxcare.1"}]}],"versions":["1.12.2"],"bundled":32},{"source":"osv","ecosystem":"Debian:13","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.11.0+dfsg-1","1.12.1+dfsg-1","1.13.1+dfsg-1","1.13.2+dfsg-1","1.14.0+dfsg-1","1.15.0-1","1.15.2-1","1.16.0-1","1.18.0-1","1.19.0-1","1.20.0-1","1.8.4+dfsg-1"]},{"source":"osv","ecosystem":"Debian:14","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.20.0-1"}]}],"versions":["1.11.0+dfsg-1","1.12.1+dfsg-1","1.13.1+dfsg-1","1.13.2+dfsg-1","1.14.0+dfsg-1","1.15.0-1","1.15.2-1","1.16.0-1","1.18.0-1","1.19.0-1","1.8.4+dfsg-1"]},{"source":"osv","ecosystem":"npm","package":"axios","ranges":[{"type":"SEMVER","events":[{"introduced":"1.7.0"},{"fixed":"1.20.0"}]}]},{"source":"osv","ecosystem":"Red Hat:hummingbird:1","package":"grafana13.1","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:13.1.6-0.6.hum1"}]}],"bundled":12},{"source":"osv","ecosystem":"Red Hat:hummingbird:1","package":"grafana12.4","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:12.4.12-0.3.hum1"}]}],"bundled":12},{"source":"osv","ecosystem":"Red Hat:hummingbird:1","package":"grafana13.2","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:13.2.1-0.9.hum1"}]}],"bundled":11},{"source":"osv","ecosystem":"Ubuntu:Pro:20.04:LTS","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.19.0+dfsg-2","0.19.0+dfsg-2ubuntu0.1~esm1"]},{"source":"osv","ecosystem":"Ubuntu:Pro:22.04:LTS","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.21.1+dfsg-1","0.23.0+dfsg-2","0.24.0+dfsg-1","0.25.0+dfsg-2","0.26.0+dfsg-1","0.26.0+dfsg-1ubuntu0.1~esm1"]},{"source":"osv","ecosystem":"Ubuntu:Pro:24.04:LTS","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.2.1+dfsg-1","1.5.1+dfsg-1","1.6.2+dfsg-1","1.6.8+dfsg-2","1.6.8+dfsg-2ubuntu0.1~esm1"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.13.2+dfsg-1build1","1.16.0-1","1.18.0-1","1.19.0-1"]},{"source":"osv","ecosystem":"Ubuntu:Pro:26.04:LTS","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.11.0+dfsg-1","1.12.1+dfsg-1","1.13.2+dfsg-1build1","1.13.2+dfsg-1ubuntu0.1~esm1"]}],"products":[{"vendor":"axios","product":"axios"}],"references":[{"url":"https://github.com/axios/axios/security/advisories/GHSA-vh66-26gq-q6x8","tags":["x_refsource_CONFIRM","exploit","advisory","web","article","report"]},{"url":"https://github.com/axios/axios/pull/11141","tags":["x_refsource_MISC","fix","web","article","report"]},{"url":"https://github.com/axios/axios/commit/d19040bda7a8be2f82c3c6e1a5bc03917daee39a","tags":["x_refsource_MISC","fix","web","article","report"]},{"url":"https://github.com/axios/axios/releases/tag/v1.20.0","tags":["x_refsource_MISC","web","article","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101908","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-vh66-26gq-q6x8"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/101xxx/CVE-2026-101908.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-101908","tags":["advisory"]},{"url":"https://github.com/axios/axios","tags":["package"]},{"url":"https://access.redhat.com/errata/RHSA-2026:74869","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101903","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-93981","tags":["report"]},{"url":"https://access.redhat.com/security/updates/classification/","tags":["article"]},{"url":"https://images.redhat.com/","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101906","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101898","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101907","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101909","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101908","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101900","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101905","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101902","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101901","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-101904","tags":["report"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_74869.json","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2538284","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-93981","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-93981","tags":["advisory"]},{"url":"https://github.com/honojs/hono/security/advisories/GHSA-hxh3-vqpv-xpqv","tags":["article"]},{"url":"https://www.vulncheck.com/advisories/hono-jsx-before-4.13.7-cross-site-scripting-via-unescaped-strings","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542571","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101898","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101898","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-3pq3-5fj3-cg6v","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542576","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101900","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101900","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-4hqw-qxg8-jxx2","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542577","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101901","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101901","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-542g-h47m-68v8","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542575","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101902","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101902","tags":["advisory"]},{"url":"https://github.com/axios/axios/releases/tag/v0.34.0","tags":["article"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-9fr6-4gfg-395g","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542580","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101903","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101903","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-c29m-xwm3-cm6r","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542579","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101904","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101904","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-j8rh-479h-cp32","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542584","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101905","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101905","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-m8m8-qj5v-23w3","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542583","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101906","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101906","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-mghh-pgcx-3jjj","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542586","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101907","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101907","tags":["advisory"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-r4gj-5m52-g5wh","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542592","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101908","tags":["advisory","report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2542593","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-101909","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-101909","tags":["advisory"]},{"url":"https://github.com/axios/axios/commit/d29be181f85f6fe93397a07b1f69606d9622637b","tags":["article"]},{"url":"https://github.com/axios/axios/security/advisories/GHSA-x97p-jq2g-jp4f","tags":["article"]},{"url":"https://access.redhat.com/errata/RHSA-2026:74871","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-93450","tags":["report"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_74871.json","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2538979","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-93450","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-93450","tags":["advisory"]},{"url":"https://github.com/go-openapi/swag","tags":["article"]},{"url":"https://github.com/go-openapi/swag/blob/v0.27.0/jsonutils/adapters/stdlib/json/adapter.go#L68","tags":["article"]},{"url":"https://github.com/go-openapi/swag/blob/v0.27.0/jsonutils/adapters/stdlib/json/ordered_map.go#L214","tags":["article"]},{"url":"https://github.com/go-openapi/swag/commit/0c24346ced59a25811e8694a915e7131d25ccb0e","tags":["article"]},{"url":"https://github.com/go-openapi/swag/security/advisories/GHSA-xh24-9qpg-8w28","tags":["article"]},{"url":"https://www.vulncheck.com/advisories/go-openapi-swag-jsonutils-before-0.27.1-uncontrolled-recursion-in-ordered-json-marshal-and-unmarshal","tags":["article"]},{"url":"https://access.redhat.com/errata/RHSA-2026:74872","tags":["advisory"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_74872.json","tags":["advisory"]},{"url":"https://ubuntu.com/security/CVE-2026-101908","tags":["report"]}],"sources":{"cve":[{"id":"CVE-2026-101908","title":"Axios: Prototype pollution gadget in fetch adapter can alter outbound requests","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","status":"published","published":"2026-09-28T17:38:55.303Z","modified":"2026-09-28T18:15:41.687Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium","assessor":"cna"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T14:20:10.143031Z"}],"euvd":[{"id":"EUVD-2026-88387","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","status":"published","published":"2026-09-28T17:38:55Z","modified":"2026-09-28T18:15:41Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium"}],"updated_at":"2026-11-02T17:27:52.759804Z"}],"ghsa":[{"id":"GHSA-vh66-26gq-q6x8","title":"Axios: Prototype pollution gadget in fetch adapter can alter outbound requests","description":"## Summary\n\nAxios 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`.\n\nAxios does not create the prototype pollution source. This is a read-side gadget that becomes exploitable after same-process prototype pollution.\n\n## Impact\n\nAn 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.\n\nThe issue is specific to fetch-adapter behavior and does not affect Node HTTP adapter requests.\n\n## Affected Functionality\n\nAffected:\n\n- `adapter: 'fetch'`.\n- Runtime environments where the fetch adapter is selected.\n- Requests where `fetchOptions` is an object that does not have safe own values for sensitive fetch init fields.\n\nNot affected:\n\n- Node HTTP adapter.\n- Requests that do not use the fetch adapter.\n- Processes where `Object.prototype` is not polluted.\n\n## Technical Details\n\n`lib/adapters/fetch.js` builds:\n\n```js\nconst resolvedOptions = {\n  ...fetchOptions,\n  signal: composedSignal,\n  method: method.toUpperCase(),\n  headers: toByteStringHeaderObject(headers.normalize()),\n  body: data,\n  duplex: 'half',\n  credentials: isCredentialsSupported ? withCredentials : undefined,\n};\n\nrequest = isRequestSupported \u0026\u0026 new Request(url, resolvedOptions);\n\nlet response = await (isRequestSupported\n  ? _fetch(request, fetchOptions)\n  : _fetch(url, resolvedOptions));\n```\n\nThe 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`.\n\nLocal 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`.\n\n## Proof of Concept of Attack\n\nConstrained local demonstration:\n\n```js\nObject.prototype.headers = { Authorization: 'Bearer POLLUTED' };\ntry {\n  await axios.get(url, {\n    adapter: 'fetch',\n    headers: { 'X-Good': 'yes' },\n    fetchOptions: {}\n  });\n} finally {\n  delete Object.prototype.headers;\n}\n```\n\nExpected safe behavior is that the sanitized axios headers remain in force. Current behavior can use the inherited fetch init headers instead.\n\n## Workarounds\n\nUse 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.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ch3\u003eOriginal report\u003c/h3\u003e\u003c/summary\u003e\n  \nHello, 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.\n\nI was testing the fetch adapter with polluted prototype values and found that `Object.prototype.headers` can change the request axios sends.\n\nThe 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.\n\nI tested it with this:\n\n```js\nimport http from 'node:http';\nimport axios from 'axios';\n\nconst server = http.createServer((req, res) =\u003e {\n  res.end(JSON.stringify({\n    authorization: req.headers.authorization || null,\n    xGood: req.headers['x-good'] || null\n  }));\n});\n\nawait new Promise(resolve =\u003e server.listen(0, '127.0.0.1', resolve));\nconst { port } = server.address();\n\nObject.prototype.headers = {\n  Authorization: 'Bearer POLLUTED'\n};\n\ntry {\n  const res = await axios.get(`http://127.0.0.1:${port}/`, {\n    adapter: 'fetch',\n    headers: { 'X-Good': 'yes' },\n    fetchOptions: {}\n  });\n\n  console.log(res.data);\n} finally {\n  delete Object.prototype.headers;\n  server.close();\n}\n```\n\nThe result I get is:\n\n```json\n{\n  \"authorization\": \"Bearer POLLUTED\",\n  \"xGood\": null\n}\n```\n\nSo the polluted Authorization header is sent, and the normal axios header is not.\n\nChanging the fetch call to pass the already resolved options fixes it for me:\n\n```diff\n- _fetch(request, fetchOptions)\n+ _fetch(request, resolvedOptions)\n```\n\n`resolvedOptions` already includes `...fetchOptions`, so custom fetch options should still work, while headers, method, body, and signal stay as clean own values.\n\u003c/details\u003e\n\n---","status":"published","published":"2026-09-30T15:13:16Z","modified":"2026-09-30T15:13:17Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T14:41:23.783773Z"}],"nvd":[{"id":"CVE-2026-101908","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","status":"published","published":"2026-09-28T18:17:19.44Z","modified":"2026-09-30T19:38:27.293Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium","assessor":"secondary"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T14:12:52.081323Z"}],"osv":[{"id":"CVE-2026-101908","title":"Axios: Prototype pollution gadget in fetch adapter can alter outbound requests","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","status":"published","published":"2026-09-28T17:38:55.303Z","modified":"2026-10-28T02:31:08.984592962Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T15:44:53.83521Z"},{"id":"DEBIAN-CVE-2026-101908","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","status":"published","published":"2026-09-28T18:17:19.44Z","modified":"2026-10-04T00:00:08.756322276Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium"}],"updated_at":"2026-11-02T15:45:48.440897Z"},{"id":"GHSA-vh66-26gq-q6x8","title":"Axios: Prototype pollution gadget in fetch adapter can alter outbound requests","description":"## Summary\n\nAxios 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`.\n\nAxios does not create the prototype pollution source. This is a read-side gadget that becomes exploitable after same-process prototype pollution.\n\n## Impact\n\nAn 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.\n\nThe issue is specific to fetch-adapter behavior and does not affect Node HTTP adapter requests.\n\n## Affected Functionality\n\nAffected:\n\n- `adapter: 'fetch'`.\n- Runtime environments where the fetch adapter is selected.\n- Requests where `fetchOptions` is an object that does not have safe own values for sensitive fetch init fields.\n\nNot affected:\n\n- Node HTTP adapter.\n- Requests that do not use the fetch adapter.\n- Processes where `Object.prototype` is not polluted.\n\n## Technical Details\n\n`lib/adapters/fetch.js` builds:\n\n```js\nconst resolvedOptions = {\n  ...fetchOptions,\n  signal: composedSignal,\n  method: method.toUpperCase(),\n  headers: toByteStringHeaderObject(headers.normalize()),\n  body: data,\n  duplex: 'half',\n  credentials: isCredentialsSupported ? withCredentials : undefined,\n};\n\nrequest = isRequestSupported \u0026\u0026 new Request(url, resolvedOptions);\n\nlet response = await (isRequestSupported\n  ? _fetch(request, fetchOptions)\n  : _fetch(url, resolvedOptions));\n```\n\nThe 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`.\n\nLocal 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`.\n\n## Proof of Concept of Attack\n\nConstrained local demonstration:\n\n```js\nObject.prototype.headers = { Authorization: 'Bearer POLLUTED' };\ntry {\n  await axios.get(url, {\n    adapter: 'fetch',\n    headers: { 'X-Good': 'yes' },\n    fetchOptions: {}\n  });\n} finally {\n  delete Object.prototype.headers;\n}\n```\n\nExpected safe behavior is that the sanitized axios headers remain in force. Current behavior can use the inherited fetch init headers instead.\n\n## Workarounds\n\nUse 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.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ch3\u003eOriginal report\u003c/h3\u003e\u003c/summary\u003e\n  \nHello, 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.\n\nI was testing the fetch adapter with polluted prototype values and found that `Object.prototype.headers` can change the request axios sends.\n\nThe 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.\n\nI tested it with this:\n\n```js\nimport http from 'node:http';\nimport axios from 'axios';\n\nconst server = http.createServer((req, res) =\u003e {\n  res.end(JSON.stringify({\n    authorization: req.headers.authorization || null,\n    xGood: req.headers['x-good'] || null\n  }));\n});\n\nawait new Promise(resolve =\u003e server.listen(0, '127.0.0.1', resolve));\nconst { port } = server.address();\n\nObject.prototype.headers = {\n  Authorization: 'Bearer POLLUTED'\n};\n\ntry {\n  const res = await axios.get(`http://127.0.0.1:${port}/`, {\n    adapter: 'fetch',\n    headers: { 'X-Good': 'yes' },\n    fetchOptions: {}\n  });\n\n  console.log(res.data);\n} finally {\n  delete Object.prototype.headers;\n  server.close();\n}\n```\n\nThe result I get is:\n\n```json\n{\n  \"authorization\": \"Bearer POLLUTED\",\n  \"xGood\": null\n}\n```\n\nSo the polluted Authorization header is sent, and the normal axios header is not.\n\nChanging the fetch call to pass the already resolved options fixes it for me:\n\n```diff\n- _fetch(request, fetchOptions)\n+ _fetch(request, resolvedOptions)\n```\n\n`resolvedOptions` already includes `...fetchOptions`, so custom fetch options should still work, while headers, method, body, and signal stay as clean own values.\n\u003c/details\u003e\n\n---","status":"published","published":"2026-09-30T15:13:16Z","modified":"2026-09-30T15:30:04.43849782Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T15:46:57.348035Z"},{"id":"RHSA-2026:74869","title":"Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update","status":"published","published":"2026-10-03T10:17:00Z","modified":"2026-10-10T10:21:33Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:22.928316Z"},{"id":"RHSA-2026:74871","title":"Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update","status":"published","published":"2026-10-03T10:17:01Z","modified":"2026-10-20T10:43:37.161085244Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:22.928316Z"},{"id":"RHSA-2026:74872","title":"Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update","status":"published","published":"2026-10-03T10:17:01Z","modified":"2026-10-03T10:32:34.60846098Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:22.928316Z"},{"id":"UBUNTU-CVE-2026-101908","description":"Axios is a promise-based HTTP client for the browser and Node.js. From 1.7.0 until 1.20.0, the fetch adapter constructs a Request with sanitized resolvedOptions but then calls fetch with the original fetchOptions. A separate same-process prototype-pollution flaw populates Object.prototype.headers so fetchOptions.headers resolves through inheritance. The inherited fetchOptions.headers value overrides the sanitized Request headers through the second argument to fetch after Request construction. Attacker-controlled request headers can alter authorization, caching, metadata-service access, or application-specific behavior. This issue is fixed in version 1.20.0.","status":"published","published":"2026-09-28T18:17:00Z","modified":"2026-10-17T12:57:55.318343056Z","cvss":[{"version":"4.0","score":6.9,"vector":"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","level":"medium"}],"updated_at":"2026-11-02T16:55:58.519486Z"},{"id":"CLSA-2026-1790854830","title":"TuxCare security update for axios (10 CVEs)","description":"TuxCare rebuilt axios to address 10 CVEs. Fixed in 1.18.1-tuxcare.1.","status":"published","published":"2026-10-01T11:40:30Z","modified":"2026-10-15T09:47:59.946123353Z","updated_at":"2026-11-02T15:43:48.65893Z"},{"id":"CLSA-2026-1791667309","title":"TuxCare security update for axios (6 CVEs)","description":"TuxCare rebuilt axios to address 6 CVEs. Fixed in 1.16.0-tuxcare.2.","status":"published","published":"2026-10-10T21:21:49Z","modified":"2026-10-15T09:46:04.062028006Z","updated_at":"2026-11-02T15:43:50.599064Z"},{"id":"CLSA-2026-1792190983","title":"TuxCare security update for axios (6 CVEs)","description":"TuxCare rebuilt axios to address 6 CVEs. Fixed in 1.13.5-tuxcare.2.","status":"published","published":"2026-10-16T22:49:43Z","modified":"2026-10-17T01:30:04.259235355Z","updated_at":"2026-11-02T15:43:51.747192Z"},{"id":"CLSA-2026-1792429081","title":"TuxCare security update for axios (12 CVEs)","description":"TuxCare rebuilt axios to address 12 CVEs. Fixed in 1.17.0-tuxcare.3.","status":"published","published":"2026-10-19T16:58:01Z","modified":"2026-10-19T19:15:21.236533641Z","updated_at":"2026-11-02T15:43:54.119956Z"},{"id":"CLSA-2026-1792429317","title":"TuxCare security update for axios (11 CVEs)","description":"TuxCare rebuilt axios to address 11 CVEs. Fixed in 1.18.0-tuxcare.2.","status":"published","published":"2026-10-19T17:01:57Z","modified":"2026-10-19T19:15:21.243167107Z","updated_at":"2026-11-02T15:43:54.119956Z"},{"id":"CLSA-2026-1792488905","title":"TuxCare security update for axios (12 CVEs)","description":"TuxCare rebuilt axios to address 12 CVEs. Fixed in 1.19.0-tuxcare.1.","status":"published","published":"2026-10-20T09:35:05Z","modified":"2026-10-20T13:45:11.467770435Z","updated_at":"2026-11-02T15:43:54.378946Z"},{"id":"CLSA-2026-1793099904","title":"TuxCare security update for axios (4 CVEs)","description":"TuxCare rebuilt axios to address 4 CVEs. Fixed in 1.16.1-tuxcare.3.","status":"published","published":"2026-10-27T11:18:24Z","modified":"2026-10-27T13:30:09.260629778Z","updated_at":"2026-11-02T15:43:55.34846Z"},{"id":"CLSA-2026-1793101849","title":"TuxCare security update for axios (32 CVEs)","description":"TuxCare rebuilt axios to address 32 CVEs. Fixed in 1.13.2-tuxcare.2.","status":"published","published":"2026-10-27T11:50:49Z","modified":"2026-10-27T13:30:17.542584318Z","updated_at":"2026-11-02T15:43:55.34846Z"},{"id":"CLSA-2026-1793109367","title":"TuxCare security update for axios (6 CVEs)","description":"TuxCare rebuilt axios to address 6 CVEs. Fixed in 1.13.6-tuxcare.1.","status":"published","published":"2026-10-27T13:56:07Z","modified":"2026-10-27T19:30:04.48363845Z","updated_at":"2026-11-02T15:43:55.34846Z"},{"id":"CLSA-2026-1793110604","title":"TuxCare security update for axios (32 CVEs)","description":"TuxCare rebuilt axios to address 32 CVEs. Fixed in 1.12.2-tuxcare.1.","status":"published","published":"2026-10-27T14:16:44Z","modified":"2026-10-27T19:30:03.618389185Z","updated_at":"2026-11-02T15:43:55.34846Z"}]}}
