{"id":"CVE-2026-44490","aliases":["CLSA-2026-1784856205","CLSA-2026-1784856218","CLSA-2026-1784856428","CLSA-2026-1784943211","CLSA-2026-1784943297","CLSA-2026-1784943412","CLSA-2026-1785117467","CLSA-2026-1785204471","CLSA-2026-1785291207","CLSA-2026-1785291682","CLSA-2026-1785380880","CLSA-2026-1785380888","CLSA-2026-1785467924","CLSA-2026-1790764333","CLSA-2026-1792163864","CLSA-2026-1792163995","CLSA-2026-1793101849","CLSA-2026-1793110604","CLSA-2026-1793874599","CLSA-2026-1794060576","DEBIAN-CVE-2026-44490","EUVD-2026-36260","GHSA-898c-q2cr-xwhg","UBUNTU-CVE-2026-44490"],"status":"published","title":"Axios: DoS \u0026 Header Injection via Prototype Pollution Read-Side Gadgets in axios merge functions","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","severity":{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00332,"percentile":0.26633,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-1321"],"published":"2026-05-29T15:54:57Z","modified":"2026-11-07T19:00:36Z","fixes":[{"ecosystem":"npm","package":"axios","fixed_in":["1.16.0","0.32.0"],"sources":["ghsa","osv"]},{"ecosystem":"TuxCare:npm","package":"axios","fixed_in":["0.26.1-tuxcare.3","0.26.0-tuxcare.3","0.24.0-tuxcare.3","0.21.4-tuxcare.3","0.19.2-tuxcare.4","0.18.1-tuxcare.4","0.15.3-tuxcare.6","0.21.2-tuxcare.1"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"node-axios","fixed_in":["1.16.0-1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.0.0"},{"fixed":"1.16.0"}]}]},{"source":"ghsa","ecosystem":"npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.31.1"},{"fixed":"0.32.0"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.7.9-tuxcare.0"},{"fixed":"1.7.9-tuxcare.1"}]}],"versions":["1.7.9"],"bundled":21},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.7.7-tuxcare.0"},{"fixed":"1.7.7-tuxcare.4"}]}],"versions":["1.7.7","1.7.7-tuxcare.1","1.7.7-tuxcare.2","1.7.7-tuxcare.3"],"bundled":3},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.7.5-tuxcare.0"},{"fixed":"1.7.5-tuxcare.3"}]}],"versions":["1.7.5","1.7.5-tuxcare.1","1.7.5-tuxcare.2"],"bundled":3},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.6.8-tuxcare.0"},{"fixed":"1.6.8-tuxcare.2"}]}],"versions":["1.6.8","1.6.8-tuxcare.1"],"bundled":8},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.6.2-tuxcare.0"},{"fixed":"1.6.2-tuxcare.2"}]}],"versions":["1.6.2","1.6.2-tuxcare.1"],"bundled":11},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.27.2-tuxcare.0"},{"fixed":"0.27.2-tuxcare.3"}]}],"versions":["0.27.2","0.27.2-tuxcare.1","0.27.2-tuxcare.2"],"bundled":4},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.26.1-tuxcare.0"},{"fixed":"0.26.1-tuxcare.3"}]}],"versions":["0.26.1","0.26.1-tuxcare.1","0.26.1-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.26.0-tuxcare.0"},{"fixed":"0.26.0-tuxcare.3"}]}],"versions":["0.26.0","0.26.0-tuxcare.1","0.26.0-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.24.0-tuxcare.0"},{"fixed":"0.24.0-tuxcare.3"}]}],"versions":["0.24.0","0.24.0-tuxcare.1","0.24.0-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.21.4-tuxcare.0"},{"fixed":"0.21.4-tuxcare.3"}]}],"versions":["0.21.4","0.21.4-tuxcare.1","0.21.4-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.19.2-tuxcare.0"},{"fixed":"0.19.2-tuxcare.4"}]}],"versions":["0.19.2","0.19.2-tuxcare.1","0.19.2-tuxcare.2","0.19.2-tuxcare.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.18.1-tuxcare.0"},{"fixed":"0.18.1-tuxcare.4"}]}],"versions":["0.18.1","0.18.1-tuxcare.1","0.18.1-tuxcare.2","0.18.1-tuxcare.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.15.3-tuxcare.0"},{"fixed":"0.15.3-tuxcare.6"}]}],"versions":["0.15.3","0.15.3-tuxcare.1","0.15.3-tuxcare.2","0.15.3-tuxcare.3","0.15.3-tuxcare.4","0.15.3-tuxcare.5"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.13.5-tuxcare.0"},{"fixed":"1.13.5-tuxcare.1"}]}],"versions":["1.13.5"],"bundled":28},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.18.0-tuxcare.0"},{"fixed":"0.18.0-tuxcare.1"}]}],"versions":["0.18.0"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.21.2-tuxcare.0"},{"fixed":"0.21.2-tuxcare.1"}]}],"versions":["0.21.2"]},{"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.12.2-tuxcare.0"},{"fixed":"1.12.2-tuxcare.1"}]}],"versions":["1.12.2"],"bundled":32},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.13.6-tuxcare.0"},{"fixed":"1.13.6-tuxcare.3"}]}],"versions":["1.13.6","1.13.6-tuxcare.1","1.13.6-tuxcare.2"],"bundled":27},{"source":"osv","ecosystem":"TuxCare:npm","package":"axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.15.2-tuxcare.0"},{"fixed":"1.15.2-tuxcare.1"}]}],"versions":["1.15.2"],"bundled":6},{"source":"osv","ecosystem":"Debian:12","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.2.1+dfsg-1","1.2.1+dfsg-1+deb12u1","1.20.0-1","1.5.1+dfsg-1","1.6.2+dfsg-1","1.6.8+dfsg-1","1.6.8+dfsg-2","1.7.3+dfsg-1","1.7.4+dfsg-1","1.7.7+dfsg-1","1.7.9+dfsg-1","1.8.4+dfsg-1"]},{"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.16.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.8.4+dfsg-1"]},{"source":"osv","ecosystem":"npm","package":"axios","ranges":[{"type":"SEMVER","events":[{"introduced":"1.0.0"},{"fixed":"1.16.0"}]}]},{"source":"osv","ecosystem":"npm","package":"axios","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.32.0"}]}]},{"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:25.10","package":"node-axios","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.7.9+dfsg-1","1.8.4+dfsg-1","1.11.0+dfsg-1"]},{"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-898c-q2cr-xwhg","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2018-16487","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44490","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-898c-q2cr-xwhg"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/44xxx/CVE-2026-44490.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-44490","tags":["advisory"]},{"url":"https://github.com/axios/axios","tags":["package"]},{"url":"https://ubuntu.com/security/CVE-2026-44490","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-44490","tags":["report"]}],"sources":{"cve":[{"id":"CVE-2026-44490","title":"Axios: DoS \u0026 Header Injection via Prototype Pollution Read-Side Gadgets in axios merge functions","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","status":"published","published":"2026-06-11T15:36:13.021Z","modified":"2026-06-11T17:23:44.278Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium","assessor":"cna"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T13:43:00.288193Z"}],"euvd":[{"id":"EUVD-2026-36260","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","status":"published","published":"2026-06-11T15:36:13Z","modified":"2026-06-11T17:23:44Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium"}],"updated_at":"2026-11-02T18:20:44.061211Z"}],"ghsa":[{"id":"GHSA-898c-q2cr-xwhg","title":"axios has DoS \u0026 Header Injection via Prototype Pollution Read-Side Gadgets in axios merge functions","description":"## Summary\n\naxios `1.15.2` exposes two read-side prototype-pollution gadgets. When `Object.prototype` is polluted by an upstream dependency in the same process (e.g. lodash `_.merge` / [CVE-2018-16487](https://nvd.nist.gov/vuln/detail/CVE-2018-16487)), axios silently picks up the polluted values:\n\n1. **Header injection** - `lib/utils.js` line 406 builds `merge()`'s accumulator as `result = {}`, so `result[targetKey]` (line 414) walks `Object.prototype` and the polluted bucket's own keys are copied into the merged headers and ride out on the wire.\n2. **Crash DoS** - `lib/core/mergeConfig.js` line 26 builds the `hasOwnProperty` descriptor as a plain-object literal. `Object.defineProperty` reads `descriptor.get`/`descriptor.set` via the prototype chain, so a polluted `Object.prototype.get` or `Object.prototype.set` makes the call throw `TypeError` synchronously on every axios request.\n\n## Affected Properties\n\n| Polluted slot | Effect |\n|---|---|\n| `Object.prototype.common` | injects headers on every method |\n| `Object.prototype.delete` / `.head` / `.post` / `.put` / `.patch` / `.query` | injects headers on the matching method |\n| `Object.prototype.get` | every axios request throws `TypeError: Getter must be a function` from `mergeConfig.js:26` |\n| `Object.prototype.set` | every axios request throws `TypeError: Setter must be a function` from `mergeConfig.js:26` |\n\nPer-request headers (`axios.request(url, { headers: {...} })`) overwrite polluted entries. Polluting `Object.prototype.get` triggers the crash before any header is built.\n\n## Proof of Concept\n\n```javascript\nconst axios = require('axios');\n\n// Finding A - header injection\nObject.prototype.common = { 'X-Poisoned': 'yes' };\nawait axios.get('http://api.example.com/users');\n// Wire request carries `X-Poisoned: yes`.\n\n// Finding B - crash DoS\nObject.prototype.get = { something: 'anything' };\nawait axios.get('http://api.example.com/users');\n// TypeError: Getter must be a function: #\u003cObject\u003e\n//     at Function.defineProperty (\u003canonymous\u003e)\n//     at mergeConfig (lib/core/mergeConfig.js:26:10)\n```\n\n## Impact\n\n- **Server hang** (`Content-Length: 99999`): receiver waits for a body that never arrives. Affects requests with a body.\n- **CL+TE conflict** (`Transfer-Encoding: chunked` rides alongside axios's auto `Content-Length`): receiver rejects with `400 Bad Request`. Affects requests with a body.\n- **Response suppression** (`If-None-Match: *`): receiver returns empty `304 Not Modified`. Affects GET / HEAD.\n- **Crash DoS** (`Object.prototype.get` / `.set`): every axios request fails synchronously with `TypeError`, not `AxiosError`, so handlers filtering on `error.isAxiosError` mishandle the failure.\n\n## Attack Flow\n\n```mermaid\nflowchart TD\n    ROOT[\"Polluted Object.prototype\u003cbr/\u003evia upstream gadget (e.g. lodash \u0026lt;= 4.17.10 _.merge / CVE-2018-16487)\u003cbr/\u003eaxios \u0026lt;= 1.15.2\"]\n\n    ROOT --\u003e CLASS_A[\"A. Arbitrary HTTP Header Injection\u003cbr/\u003ePolluted defaults.headers slot rides along on every outbound axios request\"]\n    ROOT --\u003e CLASS_B[\"B. Crash DoS via Object.prototype.get / .set\u003cbr/\u003ePolluted descriptor breaks Object.defineProperty in mergeConfig\"]\n\n    CLASS_A --\u003e PRE_A[\"Precondition: header not set per-request by the app\u003cbr/\u003eInjected via defaults.headers slot\u003cbr/\u003e(common, delete, head, post, put, patch, query)\"]\n\n    PRE_A --\u003e PA1[\"Response Suppression\u003cbr/\u003eTrigger: common = {If-None-Match: *}\u003cbr/\u003eAffects GET / HEAD\"]\n    PA1 --\u003e SA1[\"DoS\u003cbr/\u003e304 Not Modified empty\"]\n\n    PRE_A --\u003e PA2[\"Server Hang\u003cbr/\u003eTrigger: common = {Content-Length: 99999}\u003cbr/\u003eAffects requests with body\"]\n    PA2 --\u003e SA2[\"DoS\u003cbr/\u003econnection hang\"]\n\n    PRE_A --\u003e PA3[\"CL+TE Conflict\u003cbr/\u003eTrigger: common = {Transfer-Encoding: chunked}\u003cbr/\u003eAffects requests with body\"]\n    PA3 --\u003e SA3[\"DoS\u003cbr/\u003e400 Bad Request\"]\n\n    CLASS_B --\u003e SB1[\"DoS\u003cbr/\u003eTypeError: Getter / Setter must be a function\u003cbr/\u003eCrashes every axios request, not only GET\"]\n\n    %% Styles\n    style ROOT fill:#f87171,stroke:#991b1b,color:#fff\n    style CLASS_A fill:#fb923c,stroke:#9a3412,color:#fff\n    style CLASS_B fill:#fb923c,stroke:#9a3412,color:#fff\n    style PRE_A fill:#e2e8f0,stroke:#64748b,color:#1e293b\n    style PA1 fill:#fbbf24,stroke:#92400e,color:#000\n    style PA2 fill:#fbbf24,stroke:#92400e,color:#000\n    style PA3 fill:#fbbf24,stroke:#92400e,color:#000\n    style SA1 fill:#ef4444,stroke:#991b1b,color:#fff\n    style SA2 fill:#ef4444,stroke:#991b1b,color:#fff\n    style SA3 fill:#ef4444,stroke:#991b1b,color:#fff\n    style SB1 fill:#ef4444,stroke:#991b1b,color:#fff\n```\n\n## Root Cause\n\n**Finding A.** `lib/utils.js:404-429`'s `merge()` creates `result = {}` at line 406. The dangerous-keys filter on lines 408-411 blocks the write side, but the read at line 414 (`isPlainObject(result[targetKey])`) still walks the prototype chain. When `targetKey` matches a polluted slot, `result[targetKey]` returns the polluted nested object, and the recursive `merge(result[targetKey], val)` on line 415 iterates that object's own keys via `forEach` and copies them as own properties into the new accumulator. Those keys flow through `mergeConfig.js:35` → `Axios.js:148` (`utils.merge(headers.common, headers[config.method])`) → `Axios.js:155` (`AxiosHeaders.concat(...)`) → onto the wire via `http.js:677` (`headers: headers.toJSON()`) → `http.js:767` (`transport.request(options, ...)`).\n\n**Finding B.** `lib/core/mergeConfig.js:25` correctly makes `config = Object.create(null)`, but the descriptor passed on line 26 is a plain-object literal - its `get`/`set` lookups walk `Object.prototype`. A polluted non-function `Object.prototype.get` or `.set` makes `Object.defineProperty` throw `TypeError: Getter must be a function` (or `Setter must be a function`) before the call returns. The descriptor is built unconditionally on every `mergeConfig` invocation, so every axios request throws - POST, PUT, DELETE, PATCH, HEAD, QUERY, not only GET.\n\n## Suggested Fix\n\nUse null-prototype objects in place of the plain-object literals at `lib/utils.js:406` and `lib/core/mergeConfig.js:26-31`. The same descriptor pattern recurs at `lib/core/AxiosError.js:37`, `lib/core/AxiosHeaders.js:100`, `lib/utils.js:447/454/492/498`, and `lib/adapters/adapters.js:28/32`.\n\n## Resources\n\n- [CVE-2018-16487](https://nvd.nist.gov/vuln/detail/CVE-2018-16487) - `lodash.merge` prototype pollution in `lodash \u003c= 4.17.10`\n- [CWE-1321](https://cwe.mitre.org/data/definitions/1321.html) - Improperly Controlled Modification of Object Prototype Attributes","status":"published","published":"2026-05-29T15:54:57Z","modified":"2026-06-12T19:25:07Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T14:40:27.329706Z"}],"nvd":[{"id":"CVE-2026-44490","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","status":"published","published":"2026-06-11T17:16:33.027Z","modified":"2026-06-17T10:50:43.067Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium","assessor":"secondary"},{"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","assessor":"primary"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T14:12:23.485267Z"}],"osv":[{"id":"CVE-2026-44490","title":"Axios: DoS \u0026 Header Injection via Prototype Pollution Read-Side Gadgets in axios merge functions","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","status":"published","published":"2026-06-11T15:36:13.021Z","modified":"2026-10-28T02:30:58.030324175Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T15:45:04.820169Z"},{"id":"DEBIAN-CVE-2026-44490","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","status":"published","published":"2026-06-11T17:16:33.027Z","modified":"2026-10-01T03:03:14.514929698Z","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:45:55.669088Z"},{"id":"GHSA-898c-q2cr-xwhg","title":"axios has DoS \u0026 Header Injection via Prototype Pollution Read-Side Gadgets in axios merge functions","description":"## Summary\n\naxios `1.15.2` exposes two read-side prototype-pollution gadgets. When `Object.prototype` is polluted by an upstream dependency in the same process (e.g. lodash `_.merge` / [CVE-2018-16487](https://nvd.nist.gov/vuln/detail/CVE-2018-16487)), axios silently picks up the polluted values:\n\n1. **Header injection** - `lib/utils.js` line 406 builds `merge()`'s accumulator as `result = {}`, so `result[targetKey]` (line 414) walks `Object.prototype` and the polluted bucket's own keys are copied into the merged headers and ride out on the wire.\n2. **Crash DoS** - `lib/core/mergeConfig.js` line 26 builds the `hasOwnProperty` descriptor as a plain-object literal. `Object.defineProperty` reads `descriptor.get`/`descriptor.set` via the prototype chain, so a polluted `Object.prototype.get` or `Object.prototype.set` makes the call throw `TypeError` synchronously on every axios request.\n\n## Affected Properties\n\n| Polluted slot | Effect |\n|---|---|\n| `Object.prototype.common` | injects headers on every method |\n| `Object.prototype.delete` / `.head` / `.post` / `.put` / `.patch` / `.query` | injects headers on the matching method |\n| `Object.prototype.get` | every axios request throws `TypeError: Getter must be a function` from `mergeConfig.js:26` |\n| `Object.prototype.set` | every axios request throws `TypeError: Setter must be a function` from `mergeConfig.js:26` |\n\nPer-request headers (`axios.request(url, { headers: {...} })`) overwrite polluted entries. Polluting `Object.prototype.get` triggers the crash before any header is built.\n\n## Proof of Concept\n\n```javascript\nconst axios = require('axios');\n\n// Finding A - header injection\nObject.prototype.common = { 'X-Poisoned': 'yes' };\nawait axios.get('http://api.example.com/users');\n// Wire request carries `X-Poisoned: yes`.\n\n// Finding B - crash DoS\nObject.prototype.get = { something: 'anything' };\nawait axios.get('http://api.example.com/users');\n// TypeError: Getter must be a function: #\u003cObject\u003e\n//     at Function.defineProperty (\u003canonymous\u003e)\n//     at mergeConfig (lib/core/mergeConfig.js:26:10)\n```\n\n## Impact\n\n- **Server hang** (`Content-Length: 99999`): receiver waits for a body that never arrives. Affects requests with a body.\n- **CL+TE conflict** (`Transfer-Encoding: chunked` rides alongside axios's auto `Content-Length`): receiver rejects with `400 Bad Request`. Affects requests with a body.\n- **Response suppression** (`If-None-Match: *`): receiver returns empty `304 Not Modified`. Affects GET / HEAD.\n- **Crash DoS** (`Object.prototype.get` / `.set`): every axios request fails synchronously with `TypeError`, not `AxiosError`, so handlers filtering on `error.isAxiosError` mishandle the failure.\n\n## Attack Flow\n\n```mermaid\nflowchart TD\n    ROOT[\"Polluted Object.prototype\u003cbr/\u003evia upstream gadget (e.g. lodash \u0026lt;= 4.17.10 _.merge / CVE-2018-16487)\u003cbr/\u003eaxios \u0026lt;= 1.15.2\"]\n\n    ROOT --\u003e CLASS_A[\"A. Arbitrary HTTP Header Injection\u003cbr/\u003ePolluted defaults.headers slot rides along on every outbound axios request\"]\n    ROOT --\u003e CLASS_B[\"B. Crash DoS via Object.prototype.get / .set\u003cbr/\u003ePolluted descriptor breaks Object.defineProperty in mergeConfig\"]\n\n    CLASS_A --\u003e PRE_A[\"Precondition: header not set per-request by the app\u003cbr/\u003eInjected via defaults.headers slot\u003cbr/\u003e(common, delete, head, post, put, patch, query)\"]\n\n    PRE_A --\u003e PA1[\"Response Suppression\u003cbr/\u003eTrigger: common = {If-None-Match: *}\u003cbr/\u003eAffects GET / HEAD\"]\n    PA1 --\u003e SA1[\"DoS\u003cbr/\u003e304 Not Modified empty\"]\n\n    PRE_A --\u003e PA2[\"Server Hang\u003cbr/\u003eTrigger: common = {Content-Length: 99999}\u003cbr/\u003eAffects requests with body\"]\n    PA2 --\u003e SA2[\"DoS\u003cbr/\u003econnection hang\"]\n\n    PRE_A --\u003e PA3[\"CL+TE Conflict\u003cbr/\u003eTrigger: common = {Transfer-Encoding: chunked}\u003cbr/\u003eAffects requests with body\"]\n    PA3 --\u003e SA3[\"DoS\u003cbr/\u003e400 Bad Request\"]\n\n    CLASS_B --\u003e SB1[\"DoS\u003cbr/\u003eTypeError: Getter / Setter must be a function\u003cbr/\u003eCrashes every axios request, not only GET\"]\n\n    %% Styles\n    style ROOT fill:#f87171,stroke:#991b1b,color:#fff\n    style CLASS_A fill:#fb923c,stroke:#9a3412,color:#fff\n    style CLASS_B fill:#fb923c,stroke:#9a3412,color:#fff\n    style PRE_A fill:#e2e8f0,stroke:#64748b,color:#1e293b\n    style PA1 fill:#fbbf24,stroke:#92400e,color:#000\n    style PA2 fill:#fbbf24,stroke:#92400e,color:#000\n    style PA3 fill:#fbbf24,stroke:#92400e,color:#000\n    style SA1 fill:#ef4444,stroke:#991b1b,color:#fff\n    style SA2 fill:#ef4444,stroke:#991b1b,color:#fff\n    style SA3 fill:#ef4444,stroke:#991b1b,color:#fff\n    style SB1 fill:#ef4444,stroke:#991b1b,color:#fff\n```\n\n## Root Cause\n\n**Finding A.** `lib/utils.js:404-429`'s `merge()` creates `result = {}` at line 406. The dangerous-keys filter on lines 408-411 blocks the write side, but the read at line 414 (`isPlainObject(result[targetKey])`) still walks the prototype chain. When `targetKey` matches a polluted slot, `result[targetKey]` returns the polluted nested object, and the recursive `merge(result[targetKey], val)` on line 415 iterates that object's own keys via `forEach` and copies them as own properties into the new accumulator. Those keys flow through `mergeConfig.js:35` → `Axios.js:148` (`utils.merge(headers.common, headers[config.method])`) → `Axios.js:155` (`AxiosHeaders.concat(...)`) → onto the wire via `http.js:677` (`headers: headers.toJSON()`) → `http.js:767` (`transport.request(options, ...)`).\n\n**Finding B.** `lib/core/mergeConfig.js:25` correctly makes `config = Object.create(null)`, but the descriptor passed on line 26 is a plain-object literal - its `get`/`set` lookups walk `Object.prototype`. A polluted non-function `Object.prototype.get` or `.set` makes `Object.defineProperty` throw `TypeError: Getter must be a function` (or `Setter must be a function`) before the call returns. The descriptor is built unconditionally on every `mergeConfig` invocation, so every axios request throws - POST, PUT, DELETE, PATCH, HEAD, QUERY, not only GET.\n\n## Suggested Fix\n\nUse null-prototype objects in place of the plain-object literals at `lib/utils.js:406` and `lib/core/mergeConfig.js:26-31`. The same descriptor pattern recurs at `lib/core/AxiosError.js:37`, `lib/core/AxiosHeaders.js:100`, `lib/utils.js:447/454/492/498`, and `lib/adapters/adapters.js:28/32`.\n\n## Resources\n\n- [CVE-2018-16487](https://nvd.nist.gov/vuln/detail/CVE-2018-16487) - `lodash.merge` prototype pollution in `lodash \u003c= 4.17.10`\n- [CWE-1321](https://cwe.mitre.org/data/definitions/1321.html) - Improperly Controlled Modification of Object Prototype Attributes","status":"published","published":"2026-05-29T15:54:57Z","modified":"2026-09-10T03:51:04.811379218Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium"}],"cwes":["CWE-1321"],"updated_at":"2026-11-02T15:46:42.077781Z"},{"id":"UBUNTU-CVE-2026-44490","description":"Axios is a promise based HTTP client for the browser and Node.js. Prior to 0.32.0 and 1.16.0, axios exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values. (1) lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. (2) lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. This vulnerability is fixed in 0.32.0 and 1.16.0.","status":"published","published":"2026-06-11T17:16:00Z","modified":"2026-10-17T13:00:08.470294223Z","cvss":[{"version":"3.1","score":4.8,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L","level":"medium"},{"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-02T16:56:22.075798Z"},{"id":"CLSA-2026-1784856205","title":"TuxCare security update for axios (21 CVEs)","description":"TuxCare rebuilt axios to address 21 CVEs. Fixed in 1.7.9-tuxcare.1.","status":"published","published":"2026-08-04T14:52:48Z","modified":"2026-10-15T09:47:55.013314732Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1784856218","title":"TuxCare security update for axios (3 CVEs)","description":"TuxCare rebuilt axios to address 3 CVEs. Fixed in 1.7.7-tuxcare.4.","status":"published","published":"2026-08-04T14:52:48Z","modified":"2026-10-15T09:47:54.826633938Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1784856428","title":"TuxCare security update for axios (3 CVEs)","description":"TuxCare rebuilt axios to address 3 CVEs. Fixed in 1.7.5-tuxcare.3.","status":"published","published":"2026-08-04T14:52:48Z","modified":"2026-10-15T09:47:54.833756572Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1784943211","title":"TuxCare security update for axios (8 CVEs)","description":"TuxCare rebuilt axios to address 8 CVEs. Fixed in 1.6.8-tuxcare.2.","status":"published","published":"2026-08-04T14:52:49Z","modified":"2026-10-15T09:47:37.237279991Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1784943297","title":"TuxCare security update for axios (11 CVEs)","description":"TuxCare rebuilt axios to address 11 CVEs. Fixed in 1.6.2-tuxcare.2.","status":"published","published":"2026-08-04T14:52:49Z","modified":"2026-10-15T09:47:37.240229147Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1784943412","title":"TuxCare security update for axios (4 CVEs)","description":"TuxCare rebuilt axios to address 4 CVEs. Fixed in 0.27.2-tuxcare.3.","status":"published","published":"2026-08-04T14:52:49Z","modified":"2026-10-15T09:47:37.137847034Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1785117467","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.26.1-tuxcare.3.","status":"published","published":"2026-08-04T14:52:49Z","modified":"2026-10-15T09:47:37.271916206Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1785204471","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.26.0-tuxcare.3.","status":"published","published":"2026-08-04T14:52:50Z","modified":"2026-10-15T09:48:03.849409755Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1785291207","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.24.0-tuxcare.3.","status":"published","published":"2026-08-04T14:52:50Z","modified":"2026-10-15T09:48:03.789356949Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1785291682","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.21.4-tuxcare.3.","status":"published","published":"2026-08-04T14:52:50Z","modified":"2026-10-15T09:48:03.919134969Z","updated_at":"2026-11-02T15:43:46.482572Z"},{"id":"CLSA-2026-1785380880","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.19.2-tuxcare.4.","status":"published","published":"2026-08-04T14:52:50Z","modified":"2026-10-15T09:48:03.891054168Z","updated_at":"2026-11-02T15:43:46.850893Z"},{"id":"CLSA-2026-1785380888","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.18.1-tuxcare.4.","status":"published","published":"2026-08-04T14:52:51Z","modified":"2026-10-15T09:48:03.89006109Z","updated_at":"2026-11-02T15:43:46.850893Z"},{"id":"CLSA-2026-1785467924","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.15.3-tuxcare.6.","status":"published","published":"2026-08-04T14:52:51Z","modified":"2026-10-15T09:45:57.452764179Z","updated_at":"2026-11-02T15:43:46.850893Z"},{"id":"CLSA-2026-1790764333","title":"TuxCare security update for axios (28 CVEs)","description":"TuxCare rebuilt axios to address 28 CVEs. Fixed in 1.13.5-tuxcare.1.","status":"published","published":"2026-09-30T10:32:13Z","modified":"2026-10-15T09:47:53.491657971Z","updated_at":"2026-11-02T15:43:48.65893Z"},{"id":"CLSA-2026-1792163864","title":"TuxCare security update for axios (2 CVEs)","description":"TuxCare rebuilt axios to address 2 CVEs. Fixed in 0.18.0-tuxcare.1.","status":"published","published":"2026-10-16T15:17:44Z","modified":"2026-10-16T16:32:00.362102347Z","updated_at":"2026-11-02T15:43:51.747192Z"},{"id":"CLSA-2026-1792163995","title":"TuxCare security update for axios (1 CVE)","description":"TuxCare rebuilt axios to address 1 CVE. Fixed in 0.21.2-tuxcare.1.","status":"published","published":"2026-10-16T15:19:55Z","modified":"2026-10-16T16:30:12.036064105Z","updated_at":"2026-11-02T15:43:51.747192Z"},{"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-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"},{"id":"CLSA-2026-1793874599","title":"TuxCare security update for axios (27 CVEs)","description":"TuxCare rebuilt axios to address 27 CVEs. Fixed in 1.13.6-tuxcare.3.","status":"published","published":"2026-11-05T11:30:00Z","modified":"2026-11-05T13:15:17.383465117Z","updated_at":"2026-11-05T13:30:00.949926Z"},{"id":"CLSA-2026-1794060576","title":"TuxCare security update for axios (6 CVEs)","description":"TuxCare rebuilt axios to address 6 CVEs. Fixed in 1.15.2-tuxcare.1.","status":"published","published":"2026-11-07T15:09:37Z","modified":"2026-11-07T19:00:36.744054584Z","updated_at":"2026-11-07T19:21:34.633914Z"}]}}
