Safeguard
Container Security

How a Docker Image Vulnerability Scanner Works and What to Use

How a Docker image vulnerability scanner works layer by layer, what it can and cannot catch, the tools worth knowing, and how to wire scanning into your build without slowing it down.

Marcus Chen
DevSecOps Engineer
7 min read

A Docker image vulnerability scanner inspects a container image, builds an inventory of every OS package and application dependency inside it, and matches that inventory against vulnerability databases to report the known CVEs you are shipping. It answers a question you cannot answer by reading a Dockerfile: given everything that actually ended up in this image — base OS, system libraries, language packages, and whatever a RUN apt-get install pulled in transitively — what known vulnerabilities are present right now? This guide explains the mechanism, the limits, and how to use one without turning your pipeline into a bottleneck.

What is actually inside an image

A Docker image is a stack of read-only layers plus metadata. Each layer is a filesystem diff produced by an instruction in the Dockerfile. The full contents are the union of every layer, which is why an image built FROM ubuntu:22.04 inherits hundreds of packages you never named and a node:20 image inherits an entire Node runtime and its system dependencies.

That inherited weight is the point of scanning. Most vulnerabilities in a typical image live in the base image and the OS packages, not in your application code. You did not write them, you may not know they are there, and they carry CVEs like any other software. A scanner exists to make that invisible inventory visible.

How a Docker image vulnerability scanner works

The process is essentially a two-step pipeline:

  1. Inventory (SBOM generation). The scanner unpacks the image layers and catalogs what it finds: OS packages from the distro's package database (dpkg, rpm, apk), and application dependencies from language manifests and lockfiles (package-lock.json, requirements.txt, go.sum, Maven and Gradle metadata, and so on). The result is effectively a software bill of materials for the image.

  2. Match against vulnerability data. It compares each package-and-version pair against vulnerability sources — the NVD, distro-specific security trackers (Debian, Ubuntu, Alpine, Red Hat), and the GitHub Advisory Database. When an installed version falls in a vulnerable range, it reports the CVE with a severity.

Distro-aware matching matters more than people expect. Debian and Red Hat backport security fixes without changing the upstream version number, so a naive scanner that only checks the upstream version produces false positives on packages the distro has already patched. Good scanners consult the distro's own security data to avoid this.

What it catches and what it misses

A Docker image vulnerability scanner is strong at:

  • Known CVEs in OS packages and base images.
  • Known CVEs in application dependencies present in the image.
  • Often, hardcoded secrets and misconfigurations, depending on the tool.

It does not catch:

  • Unknown/zero-day vulnerabilities. It matches known CVEs; a flaw with no advisory is invisible to it. That is a separate discipline — see our guide on how to handle a zero-day vulnerability.
  • Whether a vulnerable package is actually used. A CVE in a library that ships in the image but is never executed is real but low priority. Base scanning reports presence, not reachability.
  • Runtime behavior. What the container does when running, its network exposure, and its privileges are the domain of runtime and configuration tools, not image scanning.

So an image scan tells you what known-vulnerable code you are shipping. It does not by itself tell you what an attacker can reach.

Tools worth knowing

Several capable options exist, and the ecosystem moves fast, so verify current features before you standardize:

  • Trivy (Aqua Security) — widely used open-source scanner that handles OS packages, language dependencies, secrets, and misconfigurations, and integrates easily into CI.
  • Grype (Anchore) — open-source scanner paired with Syft for SBOM generation; strong CLI ergonomics.
  • Docker Scout — Docker's own image analysis, integrated into Docker Desktop and the CLI.
  • Clair (Quay) — a long-standing scanner often used behind registries.
  • Registry-integrated scanners in Harbor, GitHub, GitLab, and the major cloud registries, which scan images as they are pushed.

The differences between them are mostly about database freshness, false-positive handling, ecosystem coverage, and how they fit your pipeline — not whether they can find a CVE at all.

Reduce vulnerabilities before you scan

Scanning tells you the score; the way to win is to ship less. The highest-leverage moves happen in the Dockerfile:

  • Use minimal base images. A slim, alpine, or distroless base carries a fraction of the packages of a full OS image, which directly shrinks the CVE count. Fewer packages, fewer known flaws.
  • Multi-stage builds. Compile in a build stage and copy only the runtime artifacts into a lean final image, so compilers and build tools never ship to production.
  • Pin and rebuild. Pin base image versions for reproducibility, but rebuild regularly so patched base images actually reach production — a pinned-and-forgotten base is how images accumulate CVEs over time.
  • Do not run as root. It does not reduce the CVE count, but it limits the blast radius when one is exploited.

For a fuller treatment, see our Docker image security best practices.

Wire it into CI/CD without the pain

The goal is scanning that gates real risk without failing builds on noise:

  • Scan on build and on push. Run the scanner in the pipeline after the image is built, and enable registry scanning so images are rechecked as vulnerability data updates — a clean image today can fail tomorrow when a new CVE lands.
  • Gate on policy, not on any finding. Failing every build on any medium-severity CVE trains teams to ignore the gate. A workable policy fails on fixable, high-or-critical severity issues and reports the rest.
  • Handle unfixable findings explicitly. Some CVEs have no fix available in the distro yet. Allow a documented, time-boxed exception rather than blocking indefinitely or silently ignoring.
  • Cache the vulnerability database in CI so scans stay fast and do not re-download the full dataset every run.

Bottom line

A Docker image vulnerability scanner is a foundational control for anyone shipping containers: it turns the invisible contents of an image into an actionable list of known vulnerabilities. But it reports presence, not exploitability, and it only knows about published CVEs. Combine it with a slim base image strategy to keep the count low, a sensible CI policy so the gate stays credible, and reachability or runtime context to prioritize what to fix first. The scanner is the smoke detector; the base-image discipline is not leaving the stove on.

FAQ

What does a Docker image vulnerability scanner actually check?

It unpacks the image, inventories every OS package and application dependency inside it, and matches those versions against vulnerability databases like the NVD, distro security trackers, and the GitHub Advisory Database, reporting the known CVEs present in the image.

Why do I get false positives from image scans?

Often because distributions backport security fixes without bumping the upstream version number. A scanner that only checks the upstream version flags packages the distro has already patched. Distro-aware scanners consult the distribution's own security data to avoid this.

Which Docker image scanner should I use?

Common capable options include Trivy, Grype, Docker Scout, and Clair, plus registry-integrated scanners in Harbor, GitHub, GitLab, and cloud registries. They differ mainly in database freshness, false-positive handling, and pipeline fit rather than raw ability to find CVEs. Verify current features when you choose.

How do I reduce the vulnerabilities a scan finds?

Ship less. Use minimal base images (slim, alpine, or distroless), use multi-stage builds so build tools do not reach production, and rebuild regularly so patched base images actually deploy. Most image CVEs come from the base image and OS packages, not your code.

Never miss an update

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