Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

CVE Scanning of Alpine base images using Multi Stage builds in Docker 17.05


The tl;dr of this post is that I want to scan my Alpine based images locally for vulnerabilities before pushing the image to an online registry. Why? Well I think it makes sense that developers have the option of checking for CVE's locally and at build time. They may choose to ignore the results but it's nice to have the option. In future this could perhaps be made into a plugin or included with the docker build function.

I mentioned this to a few folks at DockerCon and decided to put together a simple demo. Using the MultiStage build feature in Docker 17.05 we can append a CVE scan stage into our build and run a scan at build time. I also have a service running in Docker Swarm that updates the CVE database each hour and is available to all cluster nodes where image builds happen. That's for another day.

Let's get started. This first step will take a few minutes since it downloads the CVE database which is around 800mb.

Step 1

Build the cvechecker image. This image will contain the cvechecker tool and the CVE database. More details on cvechecker can be found here

docker build -t cvechecker:latest .

Step 2

There are lots of ways to run the CVE scan. Firstly let's try using the MultiStage Dockerfile to build a Wordpress container and then run the scan.

docker build -t wordpress:latest --no-cache -f Dockerfile.wordpress .

Copy the CVE.log from the image and check inside

docker run -t --rm -v ${PWD}:/results wordpress:latest /bin/sh -c "mv /tmp/CVE.log /results/wordpress.CVE.log"

Example output

File "/usr/lib/" (CPE = cpe:/a:bzip:bzip2:1.0.6:::) on host 837a64dcc771 (key 837a64dcc771)
  Potential vulnerability found (CVE-2016-3189)
  CVSS Score is 4.3
  Full vulnerability match (incl. edition/language)

This CVE was detected in the libarchive package. This package is not needed and was just an example. Remove libarchive from the Dockerfile and rebuild. No vulnerability found. Great job.

Step 3

Using the MultiStage Dockerfile we can supply a list of images and scan them all sequentially for CVE's. We could use docker-compose to replace the image name as an environment variable but in this case we will just use a bit of bash.

./ list_of_images.txt

This will pull each image, copy the contents into the cvechecker image, generate a list of executables and run the cvechecker. A results file is created per image and a final report is created.

Example output

---> Image   : nginx:1.13.0-alpine-perl
---> Sha     : sha256:dcf49000bf50c4e93d6cc84c96f8acf985998154e09f6301cff7c62314811604
---> Created : 2017-04-25T17:25:05.511678526Z
---> Log     : ./results/nginx:1.13.0-alpine-perl.CVE.log
---> Status  : 1 CVE's found

---> Image   : redis:3.2.8-alpine
---> Sha     : sha256:83638a6d3af20698d5e207febe714ac46a23a98e1d86ba36fe502fadc788daa3
---> Created : 2017-03-03T23:33:08.415849842Z
---> Log     : ./results/redis:3.2.8-alpine.CVE.log
---> Status  : No CVE's found
---> Image   : logstash:1.5.6-alpine
---> Sha     : sha256:6a7afab35097ffcacf6445366065b234371902240e2d9bf41bb3d64386352db6
---> Created : 2017-03-07T18:57:08.447747089Z
---> Log     : ./results/logstash:1.5.6-alpine.CVE.log
---> Status  : 1 CVE's found

---> Image   : logstash:1-alpine
---> Sha     : sha256:6a7afab35097ffcacf6445366065b234371902240e2d9bf41bb3d64386352db6
---> Created : 2017-03-07T18:57:08.447747089Z
---> Log     : ./results/logstash:1-alpine.CVE.log
---> Status  : 1 CVE's found

---> Image   : elasticsearch:1.7.6-alpine
---> Sha     : sha256:59103e15fe949d9735eb4ff885abb6fb5ff50bc587acb4075ac10c0d9bbb0467
---> Created : 2017-04-04T23:28:36.351775037Z
---> Log     : ./results/elasticsearch:1.7.6-alpine.CVE.log
---> Status  : 1 CVE's found

---> Image   : wordpress:4.7.4-php7.1-fpm-alpine
---> Sha     : sha256:80052e2343db98ce7ccf00b582fe024b40e07a497fdcc43f5814ba93b960d2d2
---> Created : 2017-05-06T00:15:39.364168997Z
---> Log     : ./results/wordpress:4.7.4-php7.1-fpm-alpine.CVE.log
---> Status  : 46 CVE's found

---> Image   : ruby:2.1.8-alpine
---> Sha     : sha256:f6611d75e6dc337005a23816143cfa40f96fab41860f563665c36efbb541b1e6
---> Created : 2016-03-30T21:01:49.675295954Z
---> Log     : ./results/ruby:2.1.8-alpine.CVE.log
---> Status  : 14 CVE's found

---> Image   : consul:v0.7.0
---> Sha     : sha256:2ba9010ee3cc0251be45e8b55f3154eb421df841cd93a375f9f5ab334d848291
---> Created : 2016-10-18T22:59:58.369872799Z
---> Log     : ./results/consul:v0.7.0.CVE.log
---> Status  : No CVE's found
---> Image   : python:3.4.5-alpine
---> Sha     : sha256:0eb0091592b3d8aab929e19041330d307e0e3302cf58ae8753276a2860c45037
---> Created : 2016-12-27T21:39:19.757995673Z
---> Log     : ./results/python:3.4.5-alpine.CVE.log
---> Status  : 1 CVE's found

---> Image   : rabbitmq:3.6.6-alpine
---> Sha     : sha256:1f17c5fffd2d35099050f4d224be92c424b90550cc65c76570be71d368e637cc
---> Created : 2017-03-03T23:32:16.463770425Z
---> Log     : ./results/rabbitmq:3.6.6-alpine.CVE.log
---> Status  : No CVE's found


I like free stuff. This isn't bullet-proof but it's already found a few questionable images which I would previously have used without question.

I'll tidy this up in the coming weeks and perhaps use Goss as a trigger for the CVE check.

Feel free to contact me for more details, banter, pull requests etc

@tomwillfixit @Shipitcon @DockerDublin #DockerCaptain


Code used to CVE check Alpine based images



No releases published


No packages published