Base Image Vulnerabilities: Risks, Real Examples, & How to Secure Them

Equipe de especialistas do Wiz
7 Minuto de leitura
Main takeaways from this article:
  • A base image is the foundational layer of every container.

  • Because it’s the starting point of a container, a base image’s vulnerabilities are inherited by every container that builds on it, posing a huge risk to overall container security.

  • Image scanning is a critical first step in identifying known vulnerabilities: Tools like Wiz, Trivy, and Clair scan each layer of the image against known CVEs.

  • The only defense against vulnerabilities that haven’t been reported yet? Following expert-recommended base image security best practices.

A base image is the foundational layer of every container—it acts like the container’s operating system (OS), providing core files, dependencies, and configurations needed to run your application.

Typical components of the base image include the OS, file system, configuration files, binaries, and dependencies that are required to run an application. 

In most workflows, you start from a pre‑built base image stored on a public, OCI‑compatible registry (like DockerHub) and add layers on top to produce a custom application image. For example, if you want to launch a customized Ubuntu container, the base image would be ubuntu: latest. All other instructions in the Dockerfile get executed on this Ubuntu base layer. The downside? Any vulnerability that stems from the base image is inherited by every container that builds on it.

Figure 1: Using a ubuntu: latest base image to launch a customized Ubuntu container

As containerization becomes more popular, a growing body of evidence shows that base image vulnerabilities are not just theoretical risks. For instance, a research study of the exploitability and impact of base image vulnerabilities considered 261 base images. Within that small sample, a total of 2,269 vulnerabilities were detected, and out of these, 1,983 were deemed exploitable. But that wasn’t the only bad news. A recent Sysdig report highlighted the fact that 87% of images in production have a critical or high-severity security vulnerability. 

All of these points add up to a simple takeaway: Make base‑image security a priority now, or risk shipping vulnerabilities straight into production.

Case study: An exploitable container image leads to cryptojacking

On June 25, 2020, researchers from Palo Alto Networks discovered six malicious container images containing Monero cryptocurrency-mining software (XMRig) on DockerHub. These images, published under the account azurenql (which has since been taken down), were downloaded more than 2 million times, and one associated crypto wallet contained approximately 525.38 Monero coins valued at around $36,000.

To evade network detection, the threat actor used network-anonymizing tools such as Tor and ProxyChains for the coin-mining code. A custom Python script named dao.py, configured as the ENTRYPOINT of the image, was set to trigger the cryptojacking operation when the image started. This kind of container supply-chain attack can only be caught through a systematic image-scanning process that identifies and prioritizes risks before deployment. 

Figure 2: Build sequence of malicious images (Adapted from Unit 42 by Palo Alto Networks)

Image scanning: Identifying and prioritizing risks

To prevent attackers from exploiting vulnerabilities in your containers, start with image scanning. Image scanning evaluates every layer of a container image—including the base layer and all dependencies—by comparing them against known vulnerabilities in public CVE databases.

MITRE and NVD currently list more than 250,000 known CVEs, demonstrating why manual image scanning isn’t practical. A better bet? Integrating container-security scanning tools directly into the CI/CD pipeline to help automate the heavy lifting and identify risks before threat actors exploit them. Open-source container-security tools like Trivy and Clair automate the scanning process and generate detailed reports with severity ratings. More advanced platforms like Wiz go further by scanning images, prioritizing actions based on severity, and providing actionable remediation guidance. 

But image scanning is only the first step; it can’t detect vulnerabilities that haven’t yet been disclosed. The only defense against unknown risks is to follow container security best practices, which we’ll look at next.

6 base image security best practices

The following best practices can help you procure, maintain, and monitor base images securely.

1. Use minimal base images

Stripped-down images containing only the components needed to run your application reduce the attack surface. Alpine, Rocky Linux, and Google’s distroless base images are some commonly used minimal Linux distributions. 

The most popular? Alpine Linux base images, given their image size (only 5 MB!). The Ubuntu and Debian images offered by the DockerHub image registry have packages like glibc (GNU C library) and coreutils (GNU package with standard UNIX tools like ls, cat, and mv). But Alpine uses the musl libc implementation of the C standard library and BusyBox as alternatives, resulting in a smaller attack surface, less bloat, and less resource consumption.

The following is an example of a distroless base image for a Java application:

FROM openjdk:17-jdk-slim AS build-env
COPY . /app/examples
WORKDIR /app
RUN javac examples/*.java
RUN jar cfe main.jar examples.HelloJava examples/*.class

FROM gcr.io/distroless/java17-debian12
COPY --from=build-env /app /app
WORKDIR /app
CMD ["main.jar"]

2. Use trusted sources for base images and verify their integrity

Not all base images are created equal. If you’re pulling random, unknown, and outdated images from container registries, you’re bound to introduce risks into the environment. Instead, always use official images from verified publishers. Official base images contain proper documentation, adhere to security best practices, and are vetted by the container registry. 

Figure 3: DockerHub official Alpine image and Alpine images by verified publishers

Image signing takes security a step further by ensuring an image hasn’t been tampered with. 

Traditional image-signing workflows depend on external certificate authorities and long-lived keys, which complicate key management and add extra trust roots. So in 2023, Docker introduced OpenPubkey, removing the burden by letting the image builder’s OpenID Connect (OIDC) provider itself vouch for a fresh public key, packaging identity and the key into a self-contained “PK Token.” 

Figure 4: Docker official image signing with OpenPubkey (Adapted from Docker)

3. Specify base image versions

Using the latest tag or not defining a tag at all (which resolves to the latest version by default) can feel convenient when you’re initially creating an image. The problem? Publishers might re-tag the images, meaning that when you rebuild at a later time, you may pull down an entirely different base image than the one you initially tested. This breaks reproducibility and compromises the security guarantees you had at the time of the last build.

TL;DR: Always pin base image versions to ensure reproducibility and supply chain integrity.

Unfortunately, even semantic versioning isn’t enough to stop issues in their tracks. For instance, FROM alpine:3.19 resolves to the latest patch version of 3.19. That might be 3.19.1 at the point when you specify the version, but later, it might resolve to the new latest patch version, i.e., 3.19.3

To secure supply chain integrity completely and prevent accidental breaking changes, pin the base image version to a precise digest. This could look like alpine:3.19@sha256:13b7e62…, where the digest is a SHA-256 hash that uniquely identifies the exact image. 

A word of caution: Even though it helps consistency, this specification also means that you won’t be receiving automated security patches. You’ll need to regularly monitor and apply updates or employ a service like Docker Scout to enforce policies to check whether your base image is up-to-date.

Figure 5: Different methods of specifying a base image version

4. Update base images to patch vulnerabilities

It probably goes without saying that patching known vulnerabilities and maintaining a secure runtime environment are essential. 

Given the immutable nature of base images, rebuilding with updated dependencies is the only way to keep the images up-to-date. When a new version of the base image is released, pull the update, rebuild the container, and scan the image with a tool such as Wiz to confirm that no additional vulnerabilities have been introduced. It’s helpful to stick to a routine (probably weekly or biweekly) of updating the base image to prevent further security risks.

After applying patches, the rebuilt image should also be tested in a staging environment before production deployment. 

5. Replace vulnerable base images with secure alternatives

If an image-scanning tool shows that a base image contains high-risk vulnerabilities that cannot be patched and the upstream maintainers have provided no timeline for a fix, it may be time to switch to a different base image. 

Before and after the switch, perform a compatibility test to ensure everything works well. Advanced scanners such as Wiz can also suggest practical remediation steps; for example, adopting a fixed, stable version of the current image or replacing a full OS image with Alpine or Distroless if shell access or a package manager is unnecessary.

6. Use multi-stage builds to reduce bloat and attack surface

In conventional builds, all the layers of dependency downloads, code compilations, and application packaging execute sequentially in a single build container. This makes the final image bulky and increases the security risk. Multi-stage builds ensure that only necessary production files make it into the final image, reducing both the size and the attack surface.

Multi-stage builds also make it easier to enforce dependency boundaries, keeping build tools, secrets, and temp files out of production images entirely.

Figure 6: An example of a multi-stage build (Adapted from Docker)

In figure 6, the build process is broken down into two stages, and the second stage copies essential application artifacts from the previous build stage. That way, we can leave behind the compilers, build tools, and debugging tools in the final runtime image. 

How Wiz helps secure every container base layer

Wiz secures container base layers as part of its comprehensive, graph-powered container security approach. Every container image is scanned layer by layer, including the foundational base image.

When Wiz detects a common third-party base image in your environment, it automatically adds that image as a distinct object in the Wiz Security Graph. This links the base image to every container image built on top of it, creating a full dependency chain that surfaces inherited vulnerabilities and their blast radius.

To determine base image lineage, Wiz uses a heuristic approach. When an image layer is the first in sequence and generated using an ADD file: command, Wiz marks it as the base layer—even in official images where metadata might be limited. This gives security teams the ability to:

  • Identify vulnerabilities introduced at the base layer

  • Visualize how those vulnerabilities propagate across container fleets

  • Prioritize remediation based on actual risk exposure

From the Wiz portal, you can even run queries to view all third-party base images across your environment, making it easy to spot risky images and address supply chain gaps before they become exploits.

Combined with runtime drift detection, admission controls, and full-stack risk correlation, Wiz ensures that your container foundations stay as secure as the workloads built on them.

Want to lock down your base images before vulnerabilities reach production? Download the [Container Security Cheat Sheet] and book a personalized Wiz demo to see how we surface, rank, and remediate container risks at scale.