GoogleContainerTools / GoogleContainerTools/jib
Unvalidated WWW-Authenticate realm allows registry credential exfiltration to attacker-controlled host (CWE-918 SSRF)
- Dominant language
- Java
- Stars
- 14.5k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
`RegistryAuthenticator.fromAuthenticationMethod()` parses the `realm` value directly out of a registry's `WWW-Authenticate` response header with no validation of its host, then Jib sends the configured registry credentials (Basic auth or OAuth2 refresh token) to that URL:
```java
Pattern realmPattern = Pattern.compile("realm=\"(.*?)\"");
...
String realm = realmMatcher.group(1);
```
```java
URL getAuthenticationUrl(...) {
return isOAuth2Auth(credential) ? new URL(realm) : new URL(realm + "?" + ...);
}
```
Since `realm` is fully attacker-controlled, a malicious or compromised registry can point it at an attacker-controlled HTTPS endpoint and receive the developer's real registry credentials. This fires on Jib's default, most common usage (any registry pull/push with credentials configured) — no special configuration needed.
Note: Jib's `FailoverHttpClient` already strips `Authorization` for plain-HTTP targets, which blocks the trivial plain-HTTP variant — but a realistic attacker just uses HTTPS (free to obtain), bypassing that safeguard entirely. Confirmed with a PoC: a plain-HTTP attacker endpoint received nothing, an HTTPS one received the full Basic-auth credentials.
## Why this matters now — established CWE-918 pattern with 2026 precedent
This is the same root cause (CWE-918, SSRF via unvalidated URL from an upstream response) behind several 2026 CVEs in sibling tools:
- **CVE-2026-33540** — `distribution/distribution` (reference OCI registry impl), fixed by validating realm host matches the expected upstream host
- **CVE-2026-33990** — Google's own Docker Model Runner, identical pattern
- **CVE-2026-48978** (oras-go), **CVE-2026-12566** (BBOT), **CVE-2026-24845** (Malcontent)
## Proof of Concept
Two local mock HTTPS servers (self-signed certs, loopback only):
1. Mock registry → responds to any manifest request with `401` + `WWW-Authenticate: Bearer realm="https:///steal-creds",service="..."`
2. Mock attacker collector → logs the `Authorization` header of anything it receives
```java
Jib.from(RegistryImage.named("/fake/repo:latest")
.addCredential(victimUser, victimPassword))
.containerize(...)
```
Result: the attacker collector received `Authorization: Basic ` — the real configured credential, sent to an unrelated host.
## Why I'm opening an issue rather than a PR this time
Unlike the path-traversal fix (#4522), the correct remediation here is a real compatibility tradeoff, not a one-line guard: legitimate registries commonly use a *different host* for their token-issuing auth server than the registry itself (Docker Hub's `registry-1.docker.io` redirects to `auth.docker.io`). A blind "realm host must equal registry host" check — the fix `distribution/distribution` shipped for CVE-2026-33540 — risks breaking compatibility with real registries Jib supports today (this project's own issue history shows a lot of registry-specific auth handling — Azure ACR, OpenShift, Nexus, etc.).
Options worth your team's consideration, roughly in order of increasing compatibility risk:
1. Reject non-HTTPS realms outright at the point of use (currently only the `Authorization` header gets cleared for plain HTTP; the request still fires).
2. Compare `realm`'s registrable domain (eTLD+1) against the registry's, allowing same-organization cross-subdomain realms (covers Docker Hub) while blocking unrelated domains.
3. An opt-in strict/allowlist mode for users who know their registry's real auth topology in advance.
Happy to attempt a PR for whichever direction the maintainers think is right, or to help test compatibility against known registries if that's useful.
Contributor guide
Research direction
Read RegistryAuthenticator.fromAuthenticationMethod() and getAuthenticationUrl(), then inspect FailoverHttpClient’s Authorization handling. Compare the proposed remediation options against existing registry-specific authentication behavior, including Docker Hub, Azure ACR, OpenShift, and Nexus. Done means an agreed validation policy prevents credentials reaching unrelated HTTPS realms while preserving supported registry compatibility.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, java
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100