Database/Container, Kubernetes & orchestration
Distribution: digest-pinned manifest pulls are not verified, so a registry can substitute content
Impact
A pull by digest is the one guarantee an operator has that the image bytes are the ones that were reviewed and signed off. In Distribution before 3.1.2, registry/client.(*manifests).Get() hands the response body to UnmarshalManifest without hashing it against the requested digest, so a malicious upstream registry or anyone able to tamper with the registry response can return different manifest content while claiming the requested digest in Docker-Content-Digest. The bundled pull-through proxy then caches the substituted manifest and re-serves it, so one successful substitution is amplified to every node that pulls through that mirror. On a GPU fleet this is the path by which a driver-matched CUDA base image, an inference server image, or a device-plugin DaemonSet image can be swapped fleet-wide, and the cached poison outlives the original tampering window.
Who can reach it
No authentication to the registry client is needed. The attacker must control the upstream registry being mirrored, or be positioned to tamper with responses from it (the CVSS vector records AC:H, reflecting that network position or a hostile upstream is a prerequisite). Operators running Distribution as a pull-through cache in front of an external registry are the exposed configuration.
What to do
Upgrade Distribution to 3.1.2 and restart the registry service; the fix adds verification of the response body against the requested digest. Because the pull-through proxy may already hold substituted manifests, purge the proxy cache after upgrading rather than assuming the upgrade alone cleans it. This is a daemon-level change on the registry host, not a fleet-wide maintenance event: GPU nodes need no reboot, though any workload image pulled through the affected mirror should be re-pulled and its digest re-checked.
References
Related entries
- BuildKit: oversized Dockerfile or .dockerignore exhausts buildkitd memory and kills concurrent buildsCVE-2026-93323 · BuildKit Dockerfile frontend (Dockerfile/.dockerignore size limit)Medium
- Kubernetes (kube-apiserver): A node can delete itself, and cascade-delete other objects, by adding an OwnerReferenceCVE-2025-5187 · Kubernetes (kube-apiserver)Medium
- Docker Sandboxes: case-variant OAuth hostname bypasses credential masking, leaking host tokensCVE-2026-105570 · Docker Sandboxes (OAuth token-endpoint hostname matching for managed credential injection)Medium
- JFrog Artifactory Helm chart: generated TLS private keys retained in rendered manifestsCVE-2026-66016 · JFrog Artifactory self-hosted Helm deployment (generated TLS private keys)Medium
- Kubernetes (kube-apiserver): Node address not verified when proxyingCVE-2022-3294 · Kubernetes (kube-apiserver)Medium
- Envoy: large requests crash the TCP connection pool via a null buffer watermark callbackCVE-2025-62409 · Envoy (TCP connection pool flow control / buffer watermark callbacks)Medium
This entry is curated: imported from vendor advisories with machine assistance, not yet individually verified. Confirm against your vendor's advisory before acting, and report anything wrong.