Bad Dockerfile

What’s the Big Deal ?

If you deal with Docker one of the security challenges you might come across is that of image content security.  When I talk about this I mean some way of verifying that the software in an image is:

  • Free from known software vulnerabilities in the base OS
  • Free from known software vulnerabilities in any added third party packages
  • Free from malicious software (backdoors, rootkits etc.)

This is different from image integrity which to my mind is something that can be addressed with content trust and Notary.  What we’re trying to achieve here is to make sure that any images introduced into the environment are free from software defects.  This is not news.   Probably the first decent body of work on this was done by BanyanOps in early 2015 and you can read their report here.  So, what’s happened since then ?  Well, in relative terms the market for products fighting to fill this gap has exploded and now we have a number of commercial and open source solutions that can be used to try and mitigate this risk.

Ok, I’m worried now, give me a solution.

Initially there was some vapourware out there but now there are a number of products you could look at.  This list may not be exhaustive so let me know if there’s one I missed.  Eventually I’d like to map these out in some kind of matrix so you can get an idea of what functionality each delivers but for the moment it’s just links:

Great, thanks, I’m off now to have a look

Well, this is where it get’s interesting.  How do you compare these products ?  What are your requirements ?  What suits your environment best ?  What suits your budget best ?  I can’t answer all these questions for you but I can help with the first question which is where Bad Dockerfile comes into it.  Bad Dockerfile is a deliberately vulnerable Docker image which installs software with known vulnerabilities and known CVE entries.

The simple idea behind this is if you know exactly what vulnerable software you have and the CVEs registered against these issues then it can be used as a kind of a litmus test to ‘bake off’ various solutions against one another to see how good they are.  Bad Dockerfile uses a number of methods to see how good these scanner really are:

  • Software is installed using known package management software (e.g. RPM) as well as manual installs (i.e. ./configure)
  • Product specific package management tools are also used (e.g. NPM)
  • Uses a variety of applications (e.g. command line utilities, web applications, web servers etc.)
  • Use a variety of programming/scripting languages (C, C++, Java, PHP etc.)
  • Deliberate backdoors/trojans/rootkits are installed [Not implemented yet]
  • Software is installed to non-default directories (e.g. user home directories) [Not implemented yet]
  • Use applications with vulnerable sub-components (e.g. a web app that contains a vulnerable version of Apache Struts) [Not implemented yet]
  • Supports different package management software (e.g. APT) [Not implemented yet]

Bad Dockerfile based on a CentOS 7 OS and then goes from there.  You’ll find a table below of the software installed, version, how it’s installed and the CVEs it’s known to be vulnerable to.

SoftwareVersionLanguage(s)Installation MethodInstallation PathAssociated CVEs
Drupal7.42PHPManual/opt/drupalCVE-2016-3170, CVE-2016-3169, CVE-2016-3168, CVE-2016-3164, CVE-2016-3163
Apache Tomcat7.0.69JavaManual/opt/tomcatCVE-2016-3092
Apache Tomcat7.0.42JavaRPMDefaultCVE-2013-4590, CVE-2014-0119, CVE-2014-0099, CVE-2014-0096, CVE-2014-0075
NodeJS0.10.41JavaScriptManual/opt/nodejsCVE-2016-3956, CVE-2016-2216, CVE-2016-2086
bash4.3CManual/opt/bashCVE-2014-7187, CVE-2014-7186, CVE-2014-7169, CVE-2014-6278, CVE-2014-6277, CVE-2014-6271
OpenJDK1.8.0.91JavaRPMDefaultCVE-2016-3610, CVE-2016-3606, CVE-2016-3598, CVE-2016-3587, CVE-2016-3550, CVE-2016-3508, CVE-2016-3500, CVE-2016-3485


Bad Dockerfile operates just like any other Docker image.  Just download the Bad Dockerfile Dockerfile and associated utilities into a directory of their own and build the image or download a prebuilt image and this will result in a local ‘bad-dockerfile’ image that you can then use to test scanning tools.


The one part of configuration available at the moment is the rpmsquirt utility, this will only be useful if you build the image from source yourself.  This is a utility which creates fake entries for packages in the RPM database.  If you have a specific vulnerable package that you’d like to test against the scanner just edit the rpmsquirt.dat file and enter a package name and package version.  The format of the file is simply:

<pkgname> <pkgvers>

Enter only one package/version per line and then build the image as usual.  When creating the image a fake RPM will be created using your chosen package name and version and then installed in the image.


  • Only supports RPM package management software
  • rpmsquirt is fairly basic and will only trick scanners that just look at the output of rpm to determine which packages are installed.

Word of Warning

Please be careful in that this image contains vulnerable (that is kind of the point).


Two options available here, either build the image from the source Dockerfile or download the pre-built image from Docker Hub.  If you use the pre-built image you won’t have an opportunity to customise the RPMs using rpmsquirt.

Build from Source

git clone
cd bad-dockerfile && docker build -t bad-dockerfile .


docker pull imiell/bad-dockerfile


The original idea behind Bad Dockerfile came from Ian Miell when he was trying to test various Docker image scanning solutions.  Ian is also kindly hosting the source and image on his accounts.