Docker container action should pin its image by digest
ID |
action_mutable_docker_image |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Family |
CI/ CD Security |
Tags |
ASVS50:v13.1.1, ASVS50:v15.2.1, attack-T1195.001, cicd-security, container-security, cwe-829, infrastructure, security, spvs10-v2.8.2, supply-chain |
Description
A Docker container GitHub Custom Action (runs.using: docker) whose runs.image pulls an external image through a mutable reference (docker://image:tag) instead of pinning it by digest (docker://image@sha256:…).
An image built from the action’s own Dockerfile is compiled from the action’s (scanned) first-party sources and is not flagged; only externally-pulled, mutably-referenced images are.
Security
A floating tag can be silently repointed at different image contents, so the consuming workflow ends up running attacker-controlled code — the container equivalent of the tj-actions tag-mutation supply-chain attack. Because the action’s container runs with access to the workflow’s secrets and the runner, a substituted image can exfiltrate CI credentials, tamper with build artifacts, or pivot into the pipeline.
The mutable reference also breaks reproducibility: two runs of the same workflow pinned to the same tag can execute different code.
Mitigation / Fix
Pin the external image by digest so it is immutable, or build it from the action’s own Dockerfile:
runs:
using: docker
# Immutable — pinned by digest:
image: docker://ghcr.io/acme/tool@sha256:2b1c...f09e
# Avoid — mutable tag, can be repointed at malicious contents:
# image: docker://ghcr.io/acme/tool:latest
Update the pinned digest deliberately (reviewing the new image) rather than tracking a moving tag.