Container Registry Exposure
A registry that allows anonymous pull leaks your source, and one that allows anonymous push lets an attacker replace the tag you deploy. Do both, then fix it with authentication, scoped push, and immutable tags.
What Is Container Registry Exposure?
A container registry holds your source, your configuration, and the artifact you deploy. One that allows anonymous pull hands all of that to anyone who guesses a repository name, and one that allows anonymous push lets an attacker replace a tag you are about to ship. This exercise covers both halves: watch an attacker read a private image and then poison a tag, then fix it with authentication, scoped push permissions, and immutable tags.
What You'll Learn in Container Registry Exposure
- The image contains the application source, its configuration, and its build layers, so a pull is effectively a copy of the codebase and its environment.
- An existing tag being repointed at different content, so the artifact you tested is the artifact you deploy.
- Push to the specific repositories it builds, and nothing else. A registry-wide push credential turns one compromised runner into control of every image.
- Compare the deployed image digest against the digest the pipeline recorded, since the tag can move but the digest cannot.
Container Registry Exposure — Training Steps
-
Scan for a public repo
Bob does not target Quenmoor by name. He scans self-hosted registries for ones that answer without a login, then enumerates their repositories to find one left readable. Quenmoor's registry answers, and one repository stands out.
-
A private repo left open
Bob scans self-hosted registries for repositories he should not be able to reach. Quenmoor's registry answered him without asking who he was, and one repository stands out: an internal dispatch service.
-
Public, and writable
This is an internal service, but its access policy is wide open. Bob reads the two settings that matter to him.
-
Pull it anonymously
No credentials, no membership, no request for access. Bob points Docker at the registry and pulls the production image straight down.
-
Read their production config
The image is not just code. It carries the configuration it runs with, baked into a layer. Bob starts a container from it and reads that file straight out.
-
Rebuild it with a backdoor
Reading the image was theft; overwriting it is control. Because he pulled their real production image, Bob rebuilds straight from it and adds a single layer. This is the Dockerfile.
-
The layer he added
Everything else is their image, unchanged. One RUN turns it into a foothold that ships with every deploy.
-
Tag it as their release
Bob builds the poisoned image and tags it with the exact name Quenmoor deploys from, so the registry will treat it as the production release.
-
Push a poisoned tag
Reading the image is theft. Overwriting it is control. Bob rebuilds the image with a backdoor in its entrypoint and pushes it back to the exact tag Quenmoor deploys from. The registry accepts it without asking who he is.
-
What the push bought him
The next deploy rolled Bob's tag into production, and the layer he added phoned home from inside the running service. He does not have to reach Quenmoor from outside anymore: his code is the service.