Skip to Content

Scanning Vulnerabilities in Docker images

Part of the value proposition of Containers is improved security. By running services inside containers, one can reduce the attack surface of an application.

To properly reduce the attack surface, great care must be given to the choice of base images. It’s very common to see Dockerfiles based on super-heavy base images that the application won’t need.

Multi-stage builds

Docker multi-stage builds help a lot in that matter by letting you use heavy images to build apps but prefer tiny images to actually run them. Go try Google Container Builder! It supports multi-stage builds.

Here’s a canonical example of multi-stage build for a Java application. Maven and a JDK are used to build the app. However, only the JRE is needed to run it.

FROM maven:3.5-jdk-8
ADD . ./
RUN mvn package

FROM openjdk:8u151-jre-alpine
ADD --from=0 /app/target/app.jar .
CMD ["java", "-jar", "app.jar"]

How to choose a base image?

Choosing a base image is not easy. Beginners usually copy-paste samples at the risk of using outdated images.

Also because naming things is hard some images have misleading names on the Docker Store. Eg. for Java developers, using the java base image is tempting. PLEASE DON’T. These images are deprecated, haven’t been updated for 10 months and are full of vulnerabilities which defeats the purpose of reducing the attack surface. It’s documented but still, it requires to RTM.

Vulnerability Scanning

I ran Google Container Registry Vulnerability Scanning (currently in Alpha) on multiple Java images to compare the known vulnerabilities in each.

Here’s the top 6 vulnerabilities found on the java:latest image:

Vulnerabilities in java base image

Choosing the openjdk:latest is safer:

Vulnerabilities in openjdk base image

Even better is choosing the openjdk:8u151-jre-alpine flavor. Woot! Kudos to Natanael Copa for taking such good care of Alpine!

Vulnerabilities in openjdk jre alpine

Common Vulnerabilities and Exposures (CVEs)

By the way, for this blog post, I compared the results of Container Registry Vulnerability Scanning and Docker’s own Security Scanning. As one would expect, the results are very similar since it’s ultimately using the same source for CVEs.

Sometimes Docker’s seems to raise vulnerabilities that are actually fixed. For example, it raises the CVE-2017-15874 on alpine:3.7. Looking at the alpine packages list, we see that alpine3.7 is using Busybox1.27.2-r7 that’s immune to the CVE as the list of patches shows.

Go scan your images!

comments powered by Disqus