fix: Allow same-host private/loopback registry bearer realms (NCN-114223)#1046
Merged
Conversation
Contributor
Bump google/go-containerregistry from v0.21.5 to v0.21.6 to include google/go-containerregistry#2302 (transport: allow bearer realm at same host:port as registry). The realm-URL validation introduced in go-containerregistry#2243 (shipped in v0.21.5) rejects realms whose host resolves to a private, loopback, or link-local IP. This is the right default for the cross-host SSRF case (a malicious registry pointing the token endpoint at 169.254.169.254 or a sister internal service), but it breaks `mindthegap push bundle` (and downstream `nkp push bundle`) against on-prem registries that colocate the registry and bearer- token endpoint on the same private IP. e.g. for an internal Harbor at https://10.162.182.23:5000/library the push aborts with: invalid realm in www-authenticate: realm host "10.162.182.23" is a private or link-local address v0.21.6 keeps the cross-host SSRF block but adds a same-host:port exception: when the realm URL host AND port match the registry, the private-IP check is skipped. The realm cannot escape a trust boundary the user already crossed by passing the registry reference. The transitive bumps (docker/cli, moby/moby, docker/go-connections, klauspost/compress, golang.org/x/{crypto,mod,net,sys,term,text, tools}) are pulled in by go-containerregistry v0.21.6 go.mod via MVS resolution. The containerd/stargz-snapshotter/estargz and vbatts/tar-split indirect dependencies are dropped because v0.21.6 removed estargz support (go-containerregistry#2288). Test expectations in images/manifest_test.go are updated for the unrelated OCI-spec compliance change in google/go-containerregistry#2269: mutate.AppendManifests now sets the index entry ArtifactType to the image Config.MediaType when the image manifest does not itself set artifactType. For the Docker schema2 fixture in TestManifestListForImage_RemoteImage this becomes "application/vnd.docker.container.image.v1+json" (types.DockerConfigJSON).
Adds TestPushDockerArchive_BearerAuthSameHostLoopbackRealm covering google/go-containerregistry#2258 (fixed in v0.21.6 by #2302) at the mindthegap push level. The test wraps the in-process crane registry with a Bearer-auth handler that serves WWW-Authenticate with a realm pointing back at the same httptest server (a 127.0.0.1 loopback IP literal that equals the registry host:port). It then invokes `mindthegap push` with the same basic credentials and asserts the push succeeds — i.e. that we go through token exchange, get a Bearer token, and write the image. This reproduces the exact NCN-114223 failure mode against v0.21.5: invalid realm in www-authenticate: realm host "127.0.0.1" is a private or link-local address and passes against v0.21.6, where validateRealmURL allows realms whose host:port matches the registry host:port. Bisected to confirm the test fails on v0.21.5 and passes on v0.21.6, so it would catch any future regression of the same-host bypass. The test sanity-checks that httptest is still binding to a loopback IP literal — if Go's net/http ever started returning a hostname here the test would silently stop exercising the private-IP path.
850732a to
1a23172
Compare
guillermoz-nutanix
approved these changes
May 19, 2026
Contributor
Merged
jimmidyson
pushed a commit
that referenced
this pull request
May 19, 2026
🤖 I have created a release *beep* *boop* --- ## 1.26.0 (2026-05-19) <!-- Release notes generated using configuration in .github/release.yaml at main --> ## What's Changed ### Exciting New Features 🎉 * feat: push OCI/docker image archive tarballs (NCN-113655) by @jimmidyson in #1038 ### Fixes 🔧 * fix: Allow same-host private/loopback registry bearer realms (NCN-114223) by @jimmidyson in #1046 ### Other Changes * build: bump Go toolchain to 1.26.3 by @jimmidyson in #1048 **Full Changelog**: v1.25.4...v1.26.0 --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: mesosphere-actions-pr-bot[bot] <157582460+mesosphere-actions-pr-bot[bot]@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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
github.com/google/go-containerregistryv0.21.5 → v0.21.6 to pick up google/go-containerregistry#2302 — transport: allow bearer realm at same host:port as registry.mindthegap push bundle(and downstreamnkp push bundle) regression against on-prem registries that colocate the registry and bearer-token endpoint on the same private IP. e.g. for an internal Harbor athttps://10.162.182.23:5000/librarythe push aborted withinvalid realm in www-authenticate: realm host "10.162.182.23" is a private or link-local address.TestPushDockerArchive_BearerAuthSameHostLoopbackRealmincmd/mindthegap/push/imagearchive/push_test.gothat reproduces the exact NCN-114223 error against v0.21.5 and passes against v0.21.6.Background
The realm-URL validation introduced in go-containerregistry#2243 (shipped in v0.21.5) rejects realms whose host resolves to a private, loopback, or link-local IP. This is the right default for the cross-host SSRF case (a malicious registry pointing the token endpoint at
169.254.169.254or a sister internal service), but it broke legitimate on-prem deployments that serve their own token endpoint at the same host:port as the registry. #2258 tracked the discussion; #2302 implements the agreed fix: keep the cross-host SSRF block, but skip the private-IP check when the realm URL host AND port match the registry host:port.Transitive dependency changes
Pulled in by
go-containerregistryv0.21.6'sgo.modvia MVS resolution:docker/cliv29.4.0 → v29.4.3moby/moby/apiv1.54.1 → v1.54.2moby/moby/clientv0.4.0 → v0.4.1docker/go-connectionsv0.6.0 → v0.7.0klauspost/compressv1.18.5 → v1.18.6golang.org/x/{crypto,mod,net,sys,term,text,tools}— minor bumpsDropped (v0.21.6 removed estargz support in go-containerregistry#2288):
containerd/stargz-snapshotter/estargz(indirect)vbatts/tar-split(indirect)Test fixture update
images/manifest_test.gois updated for the unrelated OCI-spec compliance change in go-containerregistry#2269:mutate.AppendManifestsnow sets the index entryArtifactTypeto the image'sConfig.MediaTypewhen the image manifest does not itself setartifactType. For the Docker schema2 fixture inTestManifestListForImage_RemoteImagethis becomes"application/vnd.docker.container.image.v1+json"(types.DockerConfigJSON).Test plan
go test -count=1 ./...passes (155 tests).TestPushDockerArchive_BearerAuthSameHostLoopbackRealmfails on v0.21.5 with the exact NCN-114223 error (invalid realm in www-authenticate: realm host "127.0.0.1" is a private or link-local address) and passes on v0.21.6 — bisected to confirm it is not a tautology.go build ./...passes.golangci-lint run ./...clean.Out of scope
The two pre-existing govulncheck stdlib findings (
GO-2026-4982,GO-2026-4980,GO-2026-4971,GO-2026-4918— allgo1.25.xfixed ingo1.25.10) are unrelated to this change.