You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Issue #2333 reported that when a registry request is permanently redirected (A→B), and host B issues a 401 WWW-Authenticate: Bearer challenge with its own realm, go-containerregistry fetches a token from B's realm but fails to apply it to the retry against B.
PR #2337 fixed #2333 by unconditionally re-attaching the refreshed token. However, this introduced a credential-leak vulnerability: bearerTransport would forward the original registry's token (minted from A's realm) to the redirected host B. PR #2349 closed that vulnerability by re-gating the re-attach on `matchesHost`, which regressed #2333.
Use Case
A client is configured to pull from registry A, but a network policy or registry gateway permanently redirects all traffic from A to B. Both registries are legitimate and trusted in this deployment.
Observed HTTP Flow:
GET https://A/v2/target-repo/manifests/latest
→ 307 Location: https://B/v2/target-repo/manifests/latest
GET https://B/v2/target-repo/manifests/latest
→ 401 WWW-Authenticate: Bearer realm="https://B/auth/token",service="B"
GET https://B/auth/token?scope=...&service=B
→ 200 OK (token minted by B's own realm)
GET https://A/v2/target-repo/manifests/latest ← library retries against A
→ 307 Location: https://B/...
GET https://B/v2/target-repo/manifests/latest ← B's token is NOT attached
→ 401 Unauthorized
Root Cause
bearerTransport is constructed once from the original registry's challenge (host A). Its realm, service, and credentials are pinned to A. On a cross-host 401 from B:
refresh() re-mints a token from A's realm with A's credentials (B's challenge realm/service are ignored beyond scope)
No mechanism exists to perform a per-host token exchange: fetch a token from B's own realm, with credentials for B, and apply it only to B
Expected Behavior
When the redirected host B returns a 401 WWW-Authenticate: Bearer challenge, the library should:
Parse B's realm, service, and scope from the challenge
Resolve credentials for B from the configured keychain
Exchange a token against B's own realm
Apply that token only to subsequent requests to B
A's credentials must never reach B. B's token must never leave B. This matches the per-host authentication model used by docker-ce and other OCI clients.
Security Invariant
This feature request must preserve the invariant closed by #2349: the original registry's token (minted from A's realm using A's credentials) must never be forwarded to the redirected host.
Background
Issue #2333 reported that when a registry request is permanently redirected (A→B), and host B issues a
401 WWW-Authenticate: Bearerchallenge with its own realm,go-containerregistryfetches a token from B's realm but fails to apply it to the retry against B.PR #2337 fixed #2333 by unconditionally re-attaching the refreshed token. However, this introduced a credential-leak vulnerability:
bearerTransportwould forward the original registry's token (minted from A's realm) to the redirected host B. PR #2349 closed that vulnerability by re-gating the re-attach on `matchesHost`, which regressed #2333.Use Case
A client is configured to pull from registry A, but a network policy or registry gateway permanently redirects all traffic from A to B. Both registries are legitimate and trusted in this deployment.
Observed HTTP Flow:
Root Cause
bearerTransportis constructed once from the original registry's challenge (host A). Itsrealm,service, and credentials are pinned to A. On a cross-host 401 from B:refresh()re-mints a token from A's realm with A's credentials (B's challenge realm/service are ignored beyond scope)matchesHostguard (restored by transport: do not re-attach bearer token after cross-host redirect #2349) correctly prevents forwarding A's token to BExpected Behavior
When the redirected host B returns a
401 WWW-Authenticate: Bearerchallenge, the library should:realm,service, andscopefrom the challengeA's credentials must never reach B. B's token must never leave B. This matches the per-host authentication model used by docker-ce and other OCI clients.
Security Invariant
This feature request must preserve the invariant closed by #2349: the original registry's token (minted from A's realm using A's credentials) must never be forwarded to the redirected host.
References