Container Security

Container Image Vulnerabilities: 2021 Year in Review

Container security matured significantly in 2021, but the vulnerability landscape in base images, registries, and runtime configurations remains concerning.

Bob
DevSecOps Engineer
6 min read

Containers Are Everywhere, and So Are Their Vulnerabilities

Container adoption crossed a tipping point in 2021. According to Datadog's Container Report, over 65% of organizations now use containers in production. Kubernetes is the de facto orchestration standard. Container images are the primary artifact format for modern application delivery.

But containers inherited a problem from the VM era: bloated base images full of packages nobody asked for. The average official Docker Hub base image contains hundreds of OS packages, many with known vulnerabilities. And most teams never audit what's in their base images.

The Base Image Problem

Vulnerability Counts in Popular Images

A scan of popular Docker Hub official images in mid-2021 reveals the scale:

  • ubuntu:20.04 — 30-50 known CVEs at any given time
  • node:16 (Debian-based) — 200+ known CVEs
  • python:3.9 (Debian-based) — 200+ known CVEs
  • openjdk:11 (Debian-based) — 250+ known CVEs
  • alpine:3.14 — 0-5 known CVEs

The discrepancy is stark. Debian and Ubuntu-based images include a full OS with hundreds of packages — many of which your application never uses. Alpine-based images are minimal, including only what's necessary for the application runtime.

Most of these CVEs are in packages your application doesn't use. A vulnerability in curl doesn't matter if your Java application never calls curl. But vulnerability scanners don't distinguish between reachable and unreachable vulnerabilities (though this is improving), so teams face alert fatigue from hundreds of findings they can't meaningfully act on.

Stale Base Images

The bigger risk isn't initial vulnerability count — it's image staleness. Many organizations build container images once and deploy them for months without rebuilding. During that time, new vulnerabilities are discovered in the base image, but the running container never gets the patches.

A Docker Hub analysis showed that over 50% of images on the registry hadn't been updated in the past six months. In production environments, the numbers are likely worse.

Supply Chain Risks in Container Images

Docker Hub Trust Model

Docker Hub hosts over 8 million container images. Only a fraction are "Official Images" maintained by Docker in partnership with upstream projects. The vast majority are community-published images with no verification of content or intent.

In 2021, researchers at Sysdig discovered that approximately 10% of the top 250 Docker Hub images contained suspicious or known-malicious content, including cryptominers and backdoors. Aqua Security separately identified over 300 malicious images on Docker Hub designed to mine cryptocurrency.

Pulling an unverified container image is equivalent to running curl | bash — you're executing untrusted code from an unverified source.

Typosquatting in Registries

The same typosquatting attacks that plague npm and PyPI exist in container registries. An attacker publishes ngnix (misspelling of nginx) or postgress (misspelling of postgres), and inattentive developers pull the wrong image.

Layer Poisoning

Container images are composed of layers. Each layer adds files to the filesystem. Malicious content can be hidden in intermediate layers that don't appear in the final filesystem view. Standard vulnerability scanners may miss content in overwritten layers.

Runtime Security

Even with clean images, runtime misconfigurations create vulnerabilities:

Running as Root

The majority of container images still run processes as root by default. A container escape vulnerability combined with root access inside the container gives an attacker root on the host. Setting USER nonroot in your Dockerfile costs nothing and eliminates an entire class of post-exploitation escalation.

Excessive Capabilities

Docker grants containers a set of Linux capabilities by default. Many containers don't need capabilities like NET_RAW (which enables packet spoofing) or SYS_PTRACE (which enables process debugging). Dropping unnecessary capabilities reduces the blast radius of a container compromise.

Read-Write Filesystems

Containers should run with read-only root filesystems wherever possible. This prevents attackers from modifying binaries, dropping persistence mechanisms, or writing malicious scripts to the container filesystem.

Privileged Mode

Running containers in privileged mode (--privileged) removes all security boundaries between the container and the host. It's the equivalent of running directly on the host with root access. Yet teams still use it — often because a container "didn't work" without it, and nobody investigated why.

2021 Container CVEs of Note

Several significant container infrastructure CVEs emerged in 2021:

  • CVE-2021-21284 — Docker daemon API vulnerability allowing directory traversal and file overwrite
  • CVE-2021-21285 — Docker daemon crash via maliciously crafted image manifest
  • CVE-2021-30465 — runc symlink-exchange vulnerability allowing container escape (runc < 1.0.0-rc95)
  • CVE-2021-25741 — Kubernetes vulnerability allowing access to host filesystem through symlink manipulation in volumes

Each of these demonstrates that the container runtime and orchestration layer itself is an attack surface, not just the application running inside containers.

Best Practices for 2022

  1. Use minimal base images — Alpine, distroless, or scratch-based images. Only include what your application needs.
  2. Rebuild regularly — Rebuild and redeploy container images at least monthly to pick up base image security patches.
  3. Scan in CI and in production — Scan images at build time to catch issues early, and scan running images to catch newly discovered vulnerabilities.
  4. Pin base image digests — Use FROM alpine@sha256:abc123... instead of FROM alpine:3.14 to ensure reproducible builds.
  5. Run as non-root — Configure containers to run as a non-root user.
  6. Implement network policies — Restrict container-to-container communication to what's necessary.
  7. Use admission controllers — Enforce security policies in Kubernetes using OPA Gatekeeper or Kyverno.

How Safeguard.sh Helps

Safeguard.sh provides comprehensive container image scanning that goes beyond basic OS package vulnerability detection. The platform analyzes every layer of your container images — base OS packages, language-specific dependencies, application artifacts, and configuration files — to produce a complete vulnerability assessment and SBOM for each image.

The platform integrates into your CI/CD pipeline to scan images at build time, preventing vulnerable images from reaching your registry. For images already in production, Safeguard.sh continuously monitors for newly disclosed vulnerabilities, alerting you when a previously clean image becomes affected by a new CVE — including critical findings like Log4Shell.

Safeguard.sh also identifies container security misconfigurations: images running as root, excessive capabilities, missing health checks, and stale base images. These configuration findings complement vulnerability scanning to provide a complete picture of your container security posture, from the base image to the running workload.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.