Base image from an untrusted registry
ID |
untrusted_registry_base_image |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Vendor |
Docker |
Resource |
Base image |
Tags |
ASVS50:v13.1.1, attack-T1195.001, cwe-829, reachable, supply-chain |
Description
A FROM instruction pulls its base image from a registry outside the vetted set (Docker Hub, GHCR, GCR, ECR, MCR, Quay, k8s). Every base image is inherited wholesale into your image, so the registry that serves it is part of your build’s trust boundary. Pulling from an arbitrary or unknown registry widens that boundary: a compromised, misconfigured, or typosquatted registry host can serve a malicious base layer that ends up running in production.
The registry host is the first path segment of the image reference when it contains a ., a port :, or equals localhost — matching Docker’s own resolution rules. The following are not flagged:
-
Implicit Docker Hub references with no registry host (e.g.
FROM alpine:3.18,FROM library/alpine). -
FROM scratch. -
References to a previous build stage in a multi-stage Dockerfile.
Examples
# Pulled from an arbitrary, non-vetted registry
FROM registry.example.io/base/app:1.2.3 (1)
# Pulled from a personal / unknown host
FROM my-registry.internal:5000/app:latest (2)
| 1 | registry.example.io is not in the vetted set — the base layer is fully trusted yet its origin is unvetted. |
| 2 | An unknown private host over which the pipeline has no supply-chain guarantees. |
Mitigation / Fix
-
Pull base images from a vetted registry (Docker Hub, GHCR, GCR, ECR, MCR, Quay, k8s), or mirror the images you need into your own trusted, access-controlled registry and reference that.
-
Combine this with pinning the image by digest (
@sha256:…) so the exact, verified layer is used on every build.
# Vetted registry, pinned by digest
FROM ghcr.io/myorg/base@sha256:bc41182d...
# or an internal mirror you control and vet
FROM registry.mycompany.com/mirror/alpine:3.19