| Field | Value |
|---|---|
| Category | CICD-SEC-3 |
| Severity | MEDIUM |
| OWASP | CICD-SEC-3: Dependency Chain Abuse |
| Auto-fix | ✗ (digest resolution requires a registry round-trip; pin manually) |
What the check does
Flags container images referenced by a mutable tag instead of an immutable@sha256: digest, across the three places a workflow pulls an image:
- a job-level
container:(scalarimage:tagor a mapping withimage:) - a
services.<name>.image - a step
uses: docker://image:tag
${{ ... }}) are skipped — the
reference isn’t knowable statically.
Why it matters
A tag such as:latest or :18 is a moving pointer. The registry (or an
attacker who compromises it, or the publishing account) can repoint that tag to
a different image between runs. Your workflow then pulls and executes code you
never reviewed — often with repository secrets and a writable token in scope.
This is the container-image analog of CICD-SEC-3 unpinned actions.
Pinning by digest makes the reference content-addressed: the bytes can’t change
without the digest changing.
Vulnerable example
Safe alternative
docker buildx imagetools inspect <image>:<tag>
(or crane digest), and keep the digest current with Dependabot or Renovate,
both of which update digest-pinned images.