✦ For everyone, free.

Practical knowledge for real and everyday life

Home

20.2.2.5 Vulnerability Scan Practice

A focused guide to Vulnerability Scan Practice, connecting core concepts with practical Docker and container operations.

Vulnerability scanning examines a Docker image's contents — the OS packages, language runtime packages, and libraries included in each layer — and reports which ones have known CVEs (Common Vulnerabilities and Exposures) registered in public security databases. Scanning provides the list of what is vulnerable and at what severity, which informs decisions about base image updates, dependency upgrades, or package removals.

Why Images Accumulate Vulnerabilities

Every package in an image is a potential vulnerability. An Ubuntu base image ships with hundreds of packages; a full language image like node:20 adds more. As time passes and new CVEs are discovered and published, images that were clean at build time accumulate known vulnerabilities without any changes to the Dockerfile or the application code. The base OS packages become outdated; library dependencies have patches that have not been pulled in.

This means vulnerability scanning is not a one-time check at image creation — it is an ongoing concern that requires periodic rescanning of deployed images.

Docker Scout

Docker Scout is Docker's integrated vulnerability scanning and policy tool. It is included with Docker Desktop and available as a CLI plugin. Scout analyzes images by inspecting their Software Bill of Materials (SBOM) — the complete inventory of packages and libraries — and correlates each package against vulnerability databases.

Scanning an Image
docker scout cves my-image:latest

Scout examines the image and outputs a list of CVEs, organized by severity:

    i New vulnerabilities detected in my-image:latest

    ✗ HIGH CVE-2024-12345
      Affecting openssl 3.0.2
      Fixed in:  3.0.11

    ✗ MEDIUM CVE-2023-98765
      Affecting libcurl 7.81.0
      Fixed in:  7.88.0

    ✓ 2 critical, 4 high, 12 medium, 8 low

Each CVE entry shows the affected package, the current version in the image, and the version where the fix is available.

Filtering by Severity
docker scout cves --only-severity critical,high my-image:latest

Limits the output to critical and high severity CVEs, which are the ones typically requiring immediate action.

Comparing Two Images
docker scout compare my-image:latest my-image:updated

Shows which CVEs were added or resolved between two versions of the image. Useful for verifying that a base image upgrade actually resolved the targeted vulnerabilities.

Getting Recommendations
docker scout recommendations my-image:latest

Scout suggests alternative base images or updated package versions that would reduce the CVE count, along with an estimate of how many vulnerabilities each change would resolve.

Trivy

Trivy is an open-source vulnerability scanner widely used in CI/CD pipelines. It scans images, filesystems, git repositories, and Kubernetes configurations.

Scanning with Trivy
trivy image my-image:latest

Trivy pulls and analyzes the image layers, then outputs a table of vulnerabilities:

┌──────────────────┬───────────────┬──────────┬────────────────────┬──────────────────┐
│    Library       │ Vulnerability │ Severity │ Installed Version  │  Fixed Version   │
├──────────────────┼───────────────┼──────────┼────────────────────┼──────────────────┤
│ libssl3          │ CVE-2024-xxxx │ HIGH     │ 3.0.2              │ 3.0.11           │
│ zlib1g           │ CVE-2022-xxxx │ MEDIUM   │ 1:1.2.11.dfsg-2    │ 1:1.2.13.dfsg-1  │
└──────────────────┴───────────────┴──────────┴────────────────────┴──────────────────┘
Filtering Severity in Trivy
trivy image --severity HIGH,CRITICAL my-image:latest
Failing a Build on Vulnerabilities

For CI pipelines, Trivy can exit with a non-zero exit code when vulnerabilities above a threshold are found:

trivy image --exit-code 1 --severity CRITICAL my-image:latest

If any critical CVEs are present, the command exits with code 1, causing the CI pipeline to fail. This prevents deploying images with known critical vulnerabilities.

Responding to Scan Results

Scan output identifies the package and the version where the fix was introduced. The remediation strategy depends on the package type:

OS packages (installed via apt, apk, yum): The fix is usually to update the base image tag or to run package updates in the Dockerfile:

FROM ubuntu:22.04
RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*

However, running apt-get upgrade in the Dockerfile updates all packages on every build, potentially pulling in breaking changes. A more controlled approach is to update the base image tag to a newer version.

Language runtime dependencies (npm packages, pip packages, go modules): Update the specific package version in the dependency manifest (package.json, requirements.txt, go.mod) and rebuild:

npm update express
docker build -t my-image:patched .
docker scout cves my-image:patched

Rescan after updating to confirm the CVE is resolved.

The Impact of Image Optimization on Scan Results

Minimal base images have fewer packages and therefore fewer CVEs. Scanning the same application against different base images illustrates this:

docker scout cves my-app:full      # FROM node:20
docker scout cves my-app:alpine    # FROM node:20-alpine
docker scout cves my-app:slim      # FROM node:20-slim

A full Debian-based node:20 image may have 200+ vulnerabilities at any given time. The node:20-alpine image typically has 30–60. A Distroless image may have under 10.

Producing smaller images through multi-stage builds and minimal base image selection is both a size optimization and a security optimization.

Scanning in CI/CD

Integrate vulnerability scanning into the build pipeline so every image is scanned before being pushed to a registry:

# GitHub Actions example
- name: Scan image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: my-image:latest
    format: table
    exit-code: 1
    severity: CRITICAL,HIGH

This pattern prevents images with critical CVEs from entering the registry. When a scan fails, the developer sees the vulnerability list and can act before the image is deployed.

Scheduled Rescanning

Because new CVEs are discovered continuously, images that were clean at build time can develop vulnerabilities while deployed. Periodic rescanning of production images — daily or weekly — catches newly published vulnerabilities:

docker scout cves registry.example.com/my-app:v1.2.3

The same image tag can show new CVEs on subsequent scans as the vulnerability databases are updated with newly discovered issues. A CVE management process includes tracking the first detection date, assigning a remediation deadline based on severity, and tracking the deployment of the patched image.