GitHub Advisoryadvisory · npm

GHSA-3w6x-2g7m-8v23 Axios: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver`

MEDIUM Published 2026-05-05 Modified 2026-05-05 Official page ↗
Aliases
CVE-2026-42044
Ecosystem
npm
Packages
axios
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N
Weaknesses
CWE-1321, CWE-915
Reviewed
2026-05-05

Affected packages

• npm axios: >= 1.0.0, < 1.15.2 → fixed in 1.15.2

Description

Vulnerability Disclosure: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver` Summary The Axios library is vulnerable to a Prototype Pollution "Gadget" attack that allows any `Object.prototype` pollution in the application's dependency tree to be escalated into surgical, invisible modification of all JSON API responses — including privilege escalation, balance manipulation, and authorization bypass. The default `transformResponse` function at `lib/defaults/index.js:124` calls `JSON.parse(data, this.parseReviver)`, where `this` is the merged config object. Because `parseReviver` is not present in Axios defaults, not validated by `assertOptions`, and not subject to any constraints, a polluted `Object.prototype.parseReviver` function is called for every key-value pair in every JSON response, allowing the attacker to selectively modify individual values while leaving the rest of the response intact. This is strictly more powerful than the `transformResponse` gadget because: 1. No constraints — the reviver can return any value (no "must return true" requirement) 2. Selective modification — individual JSON keys can be changed while others remain untouched 3. Invisible — the response structure and most values look completely normal 4. Simultaneous exfiltration — the reviver sees the original values before modification Severity: Critical (CVSS 9.1) Affected Versions: All versions (v0.x - v1.x including v1.15.0) Vulnerable Component: `lib/defaults/index.js:124` (JSON.parse with prototype-inherited reviver) CWE • CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') • CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes CVSS 3.1 Score: 9.1 (Critical) Vector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N` | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP is triggered remotely via any vulnerable dependency | | Attack Complexity | Low | Once PP exists, single property assignment. Consistent with GHSA-fvcv-3m26-pcqx scoring methodology | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | Within the application process | | Confidentiality | High | The reviver receives every key-value pair from every JSON response — full data exfiltration. In the PoC, `apiKey: "sk-secret-internal-key"` is captured | | Integrity | High | Arbitrary, selective modification of any JSON value. No constraints. In the PoC, `isAdmin: false → true`, `role: "viewer" → "admin"`, `balance: 100 → 999999`. The response looks completely normal except for the surgically altered values | | Availability | None | No crash, no error — the attack is entirely silent | Comparison with All Known Axios PP Gadgets | Factor | GHSA-fvcv-3m26-pcqx (Header Injection) | transformResponse | proxy (MITM) | parseReviver (This) | |---|---|---|---|---| | PP target | `Object.prototype['header']` | `Object.prototype.transformResponse` | `Object.prototype.proxy` | `Object.prototype.parseReviver` | | Fixed by 1.15.0? | Yes | No | No | No | | Constraints | N/A (fixed) | Must return `true` | None | None | | Data modification | Header injection only | Response replaced with `true` | Full MITM | Selective per-key modification | | Stealth | Request anomaly visible | Response becomes `true` (obvious) | Proxy visible in network | Completely invisible | | Data access | Headers only | `this.auth` + raw response | All traffic | Every JSON key-value pair | | Validated? | N/A | `assertOptions` validates | Not validated | Not validated | | In defaults? | N/A | Yes → goes through mergeConfig | No → bypasses mergeConfig | No → bypasses mergeConfig | Usage of "Helper" Vulnerabilities This vulnerability requires Zero Direct User Input. If an attacker can pollute `Object.prototype` via any other library in the stack (e.g., `qs`, `minimist`, `lodash`, `body-parser`), the polluted `parseReviver` function is automatically used by every Axios request that receives a JSON response. The developer's code is completely safe — no configuration errors needed. Root Cause Analysis The Attack Path ``` Object.prototype.parseReviver = function(key, value) { /* malicious */ } │ ▼ mergeConfig(defaults, userConfig) │ │ parseReviver NOT in defaults → NOT iterated by mergeConfig │ parseReviver NOT in userConfig → NOT iterated by mergeConfig │ Merged config has NO own parseReviver property │ ▼ transformData.call(config, config.transformResponse, response) │ │ Default transformResponse function runs (NOT overridden) │ ▼ defaults/index.js:124: JSON.parse(data, this.parseReviver) │ │ this = config (merged config object, plain {}) │ config.parseReviver → NOT own property → traverses prototype chain │ → finds Object.prototype.parseReviver → attacker's function! │ ▼ JSON.parse calls reviver for EVERY key-value pair │ │ Attacker can: read original value, modify it, return anything │ No validation, no constraints, no assertOptions check │ ▼ Application receives surgically modified JSON response ``` Why `parseReviver` Bypasses ALL Existing Protections 1. Not in defaults (`lib/defaults/index.js`): `parseReviver` is not defined in the defaults object, so `mergeConfig`'s `Object.keys({...defaults, ...userConfig})` iteration never encounters it. The merged config has no own `parseReviver` property. 2. Not in assertOptions schema (`lib/core/Axios.js:135-142`): The schema only contains `{baseUrl, withXsrfToken}`. `parseReviver` is not validated. 3. No type check: The `JSON.parse` API accepts any function as a reviver. There is no check that `this.parseReviver` is intentionally set. 4. Works INSIDE the default transform: Unlike `transformResponse` pollution (which replaces the entire transform and is caught by `assertOptions`), `parseReviver` pollution injects into the DEFAULT `transformResponse` function's `JSON.parse` call. The default function itself is not replaced, so `assertOptions` has nothing to catch. Vulnerable Code File: `lib/defaults/index.js`, line 124 ```javascript transformResponse: [ function transformResponse(data) { // ... transitional checks ... if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { // ... try { return JSON.parse(data, this.parseReviver); // ^^^^^^^^^^^^^^^^^ // this = config // config.parseReviver → prototype chain → attacker's function } catch (e) { // ... } } return data; }, ], ``` Proof of Concept ```javascript import http from 'http'; import axios from './index.js'; // Server returns a realistic authorization response const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ user: 'john', role: 'viewer', isAdmin: false, canDelete: false, balance: 100, permissions: ['read'], apiKey: 'sk-secret-internal-key', })); }); await new Promise(r => server.listen(0, r)); const port = server.address().port; // === Before Pollution === const before = await axios.get(`http://127.0.0.1:${port}/api/me`); console.log('Before:', JSON.stringify(before.data)); // {"user":"john","role":"viewer","isAdmin":false,"canDelete":false,"balance":100,...} // === Simulate Prototype Pollution === let stolen = {}; Object.prototype.parseReviver = function(key, value) { // Silently capture all original values if (key && typeof value !== 'object') stolen[key] = value; …

Related

Alias · CVE (1)

  • CVE-2026-42044 Axios is a promise based HTTP client for the browser and Node.js. vulnerability

Weakness · CWE (2)

  • CWE-1321 Improperly Controlled Modification of Object Prototype Attributes weakness
  • CWE-915 Improperly Controlled Modification of Dynamically-Determined Object Attributes weakness

References