Repository navigation
Description
Summary
#1663 fixed #1245 on main (v3): auth.Client could not resolve an authentication challenge received after a same-host redirect from the standard HTTP port to the standard HTTPS port. The v2 branch has the same defect and should get the same fix.
The defect on v2
registry/remote/auth/client.go on v2 carries the origin check from the GHSA-vh4v-2xq2-g5cg fix, without the repository refinement that main grew later:
https://github.com/oras-project/oras-go/blob/v2/registry/remote/auth/client.go#L512-L520
// If the challenge came from a different origin than originally requested
// (e.g. the request was redirected to another host or port), do not resolve
// or send the registry credentials to that origin.
// Reference: https://github.com/oras-project/oras-go/security/advisories/GHSA-vh4v-2xq2-g5cg
if resp.Request != nil && !sameHTTPOrigin(originalReq.URL, resp.Request.URL) {
return resp, nil
}sameHTTPOrigin compares the scheme, so an http:// β https:// redirect on the same host fails the check and the 401 is returned unchanged.
#1245 reports this against v2 explicitly:
The v2.6.1 fix for GHSA-vh4v-2xq2-g5cg correctly prevents
Authorizationfrom being forwarded across an HTTP-origin change. However, it also preventsauth.Clientfrom handling an authentication challenge received after a narrow, safe upgrade path.
So the behavior changed in v2.6.1 and is still present on v2. Registries that redirect http:// to https:// return 401 to any username/password or bearer flow.
What to backport
#1663. Its shape on main:
isHTTPSUpgradeβ same host, HTTP standard port to HTTPS standard portsafeHTTPSUpgradeβ validates every redirect hop, rejecting host changes, nonstandard ports, HTTPS downgrades, userinfo in the target, and aHostheader that disagrees with the URLDoretries at the HTTPS endpoint, preserving the redirected method and body, and validates a bearer realm against the HTTPS URL- Credentials obtained after an upgrade are not cached, because cache keys omit the scheme and a cached entry could later be replayed over HTTP
Authorization is still stripped on redirects, and every other origin change still blocks authentication.
One decision for whoever picks this up
It is not a clean cherry-pick. Comparing the branches:
- v2 has:
sameHTTPOrigin,canonicalHost,noCache,validateRealm,rewindRequestBody - v2 lacks:
crossesRepository,withTokenRegistryURL
safeHTTPSUpgrade calls crossesRepository in its hop loop, and Do on main calls withTokenRegistryURL. Neither exists on v2. Two options:
- Drop the
crossesRepositorycalls. Keeps the backport narrow and matches v2's current protection, which never checked repository crossing. - Backport
crossesRepositoryas well. Widens v2's security check beyond the redirect fix, which is a larger behavior change than this issue asks for.
Option 1 is the smaller change; option 2 brings v2 closer to main. Worth deciding deliberately rather than resolving it in a rebase.
Scope
If this should ship in v2.7.0 it affects #1660, which is open and otherwise ready. Otherwise it lands in v2.7.1.
Related
- Re-support same-host http-to-https redirectΒ #1245 β the report
- fix(auth): authenticate after same-host HTTPS upgradesΒ #1663 β the fix on
main - GHSA-vh4v-2xq2-g5cg β the advisory whose fix introduced the regression in v2.6.1
Activity
TanvirTian commentedon Oct 22, 2026
i'd like to work on this issue if no one is already working on it
TerryHowe commentedon Oct 22, 2026
Done