Vulnerability Assessment is one of those foundational IT Security tasks that often gets overlooked or thought to be reasonably straightforward, where you can actually find some interesting complications that make it trickier than expected.

Generally, most companies will include VA as part of their overall operational security processes, looking to assure that the software they’re deploying is relatively free of unpatched security vulnerabilities.

This post will look a bit at how assessing vulnerabilities of container images for outdated operating system packages is handled and some things to be aware of. We’ll exclude Windows container images to keep things (relatively) straightforward and stick to operating system level vulnerabilities.

Overview

Most Docker images are based on specific Linux distributions and make use of the package managers that those distributions provide to deploy software like tooling and libraries that support the application running in containers based on that image.

So if we’re looking to assess whether there are known vulnerabilities in our images, it would seem possible to use the data provided by the distributions about package versions and CVEs that are patched in them, to assess whether a given image has unpatched vulnerabilities, so far … so simple!

Tooling

To take a practical look at how this works, we can use some of the Open Source container vulnerability scanning tools that are available. For this post we’ll look at three

For the examples below, I set up all three scanners to run locally (e.g. without setting up a container registry). For Anchore I used their Docker compose file and Ancore CLI, for clair I used clair-local-scan and for Trivy, I just used the binary as it comes from their repo. A side note on these is that, from the perspective of setup processes for standalone usage, Trivy is by far the easiest to get working.

Scanning Common Base Images

So now we’ve got three scanners setup, let’s take a look at some common base images and see what they come up with. All three tools provide a JSON output option, so we can use that to create parseable results for analysis.

TL;DR.

If you don’t want to read down a couple of points to note

  • Despite the task seeming relatively simple, even in base images different container vulnerability scanners produce quite different results
  • The scanning engines support different sets of base images, so that should be noted when you’re assessing which one to use
  • Even in a fully updated base image, there can still be outstanding CVEs, depending on the update cycle of both Docker Hub and the underlying distribution.

Summary of Vulnerability Numbers

  Ubuntu:18.04 Ubuntu:20.04 Debian:stable Centos:8
Anchore 71 23 47 74
Clair 38 0 89 1
Trivy 73 26 88 N/A

Result Details

Ubuntu:18.04

This is a very commonly used base image. We’re using the latest version with that tag from Docker Hub. First question is, when we scan this image, how many vulnerabilities does each scanner think we have?

Vulnerability Count

Anchore thinks the vuln count is : 71
Clair thinks the vuln count is : 38
Trivy thinks the vuln count is : 73

This is moderately interesting already. If you’re using an updated image from Docker Hub, you might think there would be no unpatched issues, but you’d be wrong. One interesting piece about these issue counts is that (in this case) it turns out that the CVEs referenced are the same but that some of the scanners have multiple vulnerabilities for a single CVE.

Next question, what severity do the various scanners apply to these vulnerabilities

Vulnerability Severities

Anchore Severity Counts : {"Low"=>31, "Negligible"=>23, "Medium"=>17}
Clair Severity Counts : {"Medium"=>11, "Low"=>20, "Negligible"=>7}
Trivy Severity Counts : {"LOW"=>55, "MEDIUM"=>18}

Some relatively major differences there too.

Ubuntu:20.04

Lets try the newest stable release of Ubuntu and see what that shows up. Here, Clair doesn’t notice any issues whilst both Anchore and Trivy report over twenty

Vulnerability Count

Anchore thinks the vuln count is : 23
Clair thinks the vuln count is : 0
Trivy thinks the vuln count is : 26

On severities, Trivy includes a high, where all of Anchore’s severities are medium or low.

Vulnerability Severities

Anchore Severity Counts : {"Low"=>11, "Negligible"=>5, "Medium"=>7}
Clair Severity Counts : {}
Trivy Severity Counts : {"MEDIUM"=>9, "LOW"=>16, "HIGH"=>1}

Debian:stable

Here the numbers are switched around again with Clair and Trivy reporting quite a few more issues than Anchore. An interesting point is that whilst Clair and Trivy’s total vulnerability counts are similar, the referenced CVEs have quite a few differences.

Vulnerability Count

Anchore thinks the vuln count is : 47
Clair thinks the vuln count is : 89
Trivy thinks the vuln count is : 88

Vulnerability severity

Anchore Severity Counts : {"Negligible"=>46, "Medium"=>1}
Clair Severity Counts : {"Low"=>21, "Negligible"=>45, "Unknown"=>23}
Trivy Severity Counts : {"LOW"=>69, "MEDIUM"=>17, "HIGH"=>2}

Centos:8

Another commonly used base image here the results are interesting, in that Trivy doesn’t recognize the OS at all and Anchore comes out with a lot more vulnerabilities than Clair.

Vulnerability Count

Anchore thinks the vuln count is : 74
Clair thinks the vuln count is : 1
Trivy thinks the vuln count is : 0

Vulnerability Severities

Anchore Severity Counts : {"Low"=>23, "High"=>4, "Medium"=>47}
Clair Severity Counts : {"High"=>1}
Trivy Severity Counts : {}

raesene

Security Geek, Kubernetes, Docker, Ruby, Hillwalking