Container image is not pinned
ID |
unpinned_container_image |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Vendor |
Kubernetes |
Resource |
General Security |
Tags |
ASVS50:v13.1.1, CWE:1357, reachable, supply-chain |
Description
A container names an image that does not say which build will run: no tag, an explicit :latest, or
a floating tag re-pushed on every release.
In Kubernetes the consequence is sharper than elsewhere, because a pod that is rescheduled pulls again: two replicas of the same Deployment can be running different code, and a rollback to a previous manifest does not roll the image back.
The Compose counterpart is compose_unpinned_image and the Dockerfile one is
unpinned_version_base_image.
Examples
Reported:
spec:
containers:
- name: worker
image: example/worker:latest
Not reported:
spec:
containers:
- name: worker
image: example/worker:1.4.2
Mitigation / Fix
Pin the image, by version and preferably by digest, and let a controlled update change it:
spec:
containers:
- name: worker
image: example/worker@sha256:9f2b3d2a1c0e4f5a6b7c8d9e0f1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c
Leave imagePullPolicy alone. Kubernetes already defaults to IfNotPresent for a digest or a
non-latest tag, and setting it explicitly on a shared cluster works against the
api_server_enable_admission_plugins_always_pull_images rule in this same catalogue: once an image
is cached on a node, any pod from any user can run it by naming it, with no check that the user
holds credentials to pull it. On a multi-tenant cluster keep Always, or enable the
AlwaysPullImages admission plugin.