transport: block redirects from token server to private/link-local addresses (SSRF fix) by evilgensec · Pull Request #2292 · google/go-containerregistry (original) (raw)

@evilgensec

refreshOauth and refreshBasic constructed http.Client without a CheckRedirect handler, allowing a malicious token server to issue an HTTP redirect to an internal address (e.g. 169.254.169.254) that would pass the initial validateRealmURL check but still reach private services.

Add realmRedirectCheck, which applies the same scheme and private-IP restrictions as validateRealmURL to every redirect hop during a token-fetch request. Wire it as CheckRedirect on both clients.

Add TestTokenServerRedirectSSRF to confirm the redirect is rejected.

@evilgensec mentioned this pull request

May 12, 2026

4 tasks

Subserial

@evilgensec

@evilgensec

Subserial

@evilgensec

Subserial pushed a commit to Subserial/go-containerregistry that referenced this pull request

May 15, 2026

@evilgensec @Subserial

…dresses (SSRF fix) (google#2292)

refreshOauth and refreshBasic constructed http.Client without a CheckRedirect handler, allowing a malicious token server to issue an HTTP redirect to an internal address (e.g. 169.254.169.254) that would pass the initial validateRealmURL check but still reach private services.

Add realmRedirectCheck, which applies the same scheme and private-IP restrictions as validateRealmURL to every redirect hop during a token-fetch request. Wire it as CheckRedirect on both clients.

Add TestTokenServerRedirectSSRF to confirm the redirect is rejected.

Subserial pushed a commit that referenced this pull request

Jun 12, 2026

@tufstraka

Add URL validation to getNextPageURL() to ensure pagination Link headers point to the same registry host. This prevents SSRF attacks where a malicious registry could include a Link header pointing to internal services like cloud metadata endpoints (169.254.169.254).

The fix validates that:

  1. The pagination URL scheme matches the registry scheme
  2. The pagination URL host matches the registry host

This is consistent with SSRF protections added in PRs #2292, #2293, #2295 for other code paths.

The same SSRF vulnerability that affected google.List() also exists in remote.List() and remote.Catalog(). A malicious registry can return a Link header pointing to internal services.

This commit adds SSRF protection to the remote package's pagination handling, using the same validation approach.

Update test calls to getNextPageURL in pkg/v1/remote/list_test.go to pass the required name.Repository argument, matching the new function signature that includes SSRF validation.

Also update makeResp helper to include a Request with URL for proper ResolveReference behavior, and adjust test assertions accordingly.


Co-authored-by: tufstraka tufstraka@users.noreply.github.com

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})