# Distribution affected by pull-through cache credential exfiltration via www-authenticate bearer realm

Distribution's pull-through cache trusts the bearer realm from upstream WWW-Authenticate, sending configured upstream basic-auth credentials to an attacker-chosen token endpoint.

- Payout: Research
- Severity: high
- Program: Distribution
- Found by: 1seal
- Disclosed: 2026-04-06
- CVE: CVE-2026-33540
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-3p65-76g6-3w7r
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-3p65-76g6-3w7r
- Tags: area:cloud domain:infra impact:data-leak kind:research platform:ghsa sev:high tech:go technique:chained technique:source-review vuln:secrets-leak vuln:ssrf

**Target:** Pull-through cache proxy auth flow (registry/proxy/proxyauth.go, internal/client/auth/session.go)
**Root cause:** getAuthURLs extracts the bearer realm from the upstream WWW-Authenticate challenge without validating it matches the upstream registry host; fetchTokenWithBasicAuth then sends configured upstream credentials to that realm.
**Steps:**
1. Configure distribution in pull-through cache mode pointing at an upstream registry.
2. Attacker controls (or MitMs) the upstream and returns a `WWW-Authenticate: Bearer realm=<attacker URL>` challenge.
3. getAuthURLs (registry/proxy/proxyauth.go:66-81) parses realm without host validation.
4. fetchToken (session.go:485-510) requests the attacker realm; fetchTokenWithBasicAuth (session.go:429-434) sends upstream credentials via Basic auth.
5. Observe `basic_auth_sent=true realm_host=127.0.0.1` in the local harness (make canonical) vs control showing realm_validation=PASS basic_auth_sent=false.
**How found:** Code review of the pull-through cache auth flow, recognizing the same vulnerability class as containerd CVE-2020-15157 (unvalidated realm in WWW-Authenticate) applied to distribution's proxy auth.
**Exploitation:** Attacker gains control of the upstream registry (compromised registry, stale domain, malicious mirror) or a MitM position on the upstream connection, returns a crafted bearer challenge with an attacker-hosted realm, and receives the proxy's configured upstream credentials via Basic auth on the token request.
**Escalation:** Impact rises if the configured upstream credentials are broader (e.g. cloud IAM credentials) rather than registry-scoped.
**Insight:** Any client that parses WWW-Authenticate bearer realm and then attaches stored credentials to it is a credential-exfil sink; check whether realm host is bound to the configured upstream before sending auth.

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

**PoC harness reproduction commands**

```
unzip -q -o poc.zip -d poc
cd poc
make canonical
make control
```

**Proof marker showing basic auth sent to attacker realm**

```
[CALLSITE_HIT]: getAuthURLs::configureAuth
[PROOF_MARKER]: basic_auth_sent=true realm_host=127.0.0.1 account_param=user authorization_prefix=Basic
```

