In last week’s blog, we covered how to create custom policies that can be used to evaluate your container images as part of your CI/CD pipeline or at any time during their lifetime. We explained that you should always perform a CVE scan of your container but that this is only the first step, in fact security vulnerabilities in the operating system packages are just the tip of the iceberg in terms of the tests that you should be performing.
Today we want to dig a little deeper into CVEs. Let’s start by looking at the NGINX image in the Anchore Navigator. NGINX is one of the most downloaded images on DockerHub and the chances are that if you are reading this blog you are running NGINX somewhere in your environment.
The following link will take you directly to the Security tab for the image to show you the CVEs found in this image.
At first glance, looking at the summary, you will probably be concerned: 18 high-level CVEs. The chances are that your policies are configured to fail the image and stop the deployment if any high-level CVEs are found but it’s not that simple.
Let’s drill down into the details of the first two entries in the list.
Here you can see that two packages include the following vulnerability: CVE-2016-7943 and that, currently, there is no fix available in the version of Debian that this container is built from. You may be tempted to ignore any CVE for which there is not yet a fix, however, there are may not be a fix because one is not required or perhaps there is a real vulnerability but the vendor has not yet released a patch. So let’s click on the link for CVE-2016-7943 to dig a little deeper.
This CVE has been issued against the libx11 library for X.org the graphical display server.
Libx11 is present in the image as it was pulled in by dependencies (libx11 -> libxpm4 -> nginx-module-image-filter).
The National Vulnerability Database (NVD), maintained by NIST, has this categorized as high severity. As you can see from the description this vulnerability may allow remote X servers to gain higher-level privileges. At the bottom of the page you will see the following notes:
Here you can see that the Debian security team has described it as a “minor issue”.
Given the Debian security team’s assessment, not to mention the fact that there will be no remote X window connections to this server we can safely ignore this high vulnerability.
That’s 1 down, 17 more to go …….
For the sake of this example, let’s presume that all the 18 high-level CVEs aren’t exploitable in our image. While that is certainly reassuring it’s also a lot of work for a DevOps engineer to review all CVEs in an image - there’s just too much noise and mistakes are bound to be made.
At Anchore we don’t believe that we should be producing lists of issues for engineers to review, the result of a policy evaluation should be a decision, does the image pass or fail? You will see that result on the Policy tab for this image.
We have evaluated this image with our default policy and with no whitelist, hence the failure.
The Anchore engine supports the notion of whitelists that allow users to define exceptions that should be ignored. For example, if we included CVE-2016-7943 in our whitelist then those first two high vulnerabilities would not have been shown in our policy evaluation.
Let’s move the command line to continue.
We’ll start by pulling down the latest nginx image and performing an analysis using Anchore.
# docker pull nginx:latest
# anchore analyze --image=nginx:latest
Next, we’ll create a very simple policy file called mypolicy, containing only two checks - for High and Critical CVEs
ANCHORESEC:VULNCRITICAL:STOP
ANCHORESEC:VULNHIGH:STOP
And then run a gate check against the image
# anchore gate --image=nginx:latest --policy=mypolicy
+--------------+------------------------+------------+----------+-----------------------------+-------------+ | Image Id | Repo Tag | Gate | Trigger | Check Output | Gate Action | +--------------+------------------------+------------+----------+-----------------------------+-------------+ | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libx11-data | | | | | | | (CVE-2016-7943 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-7943) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libx11-6 | | | | | | | (CVE-2016-7943 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-7943) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libc-bin | | | | | | | (CVE-2014-9761 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2014-9761) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - multiarch-support | | | | | | | (CVE-2014-9761 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2014-9761) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libc6 | | | | | | | (CVE-2014-9761 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2014-9761) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libx11-data | | | | | | | (CVE-2016-7942 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-7942) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libx11-6 | | | | | | | (CVE-2016-7942 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-7942) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libxml2 | | | | | | | (CVE-2016-4448 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-4448) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libvpx1 | | | | | | | (CVE-2015-1258 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2015-1258) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libtiff5 | | | | | | | (CVE-2015-7554 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2015-7554) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libtiff5 | | | | | | | (CVE-2016-9535 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-9535) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libxml2 | | | | | | | (CVE-2016-1761 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2016-1761) | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability found in | STOP | | | | | | package - libtiff5 | | | | | | | (CVE-2017-5225 - https | | | | | | | ://security-tracker.debian. | | | | | | | org/tracker/CVE-2017-5225) | | | 5e69fe4b3c31 | docker.io/nginx:latest | FINAL | FINAL | | STOP | +--------------+------------------------+------------+----------+-----------------------------+-------------+
For the sake of this example let’s presume that all of these CVEs have been analyzed and based on the results whitelisted. We’ll create a file called mywhitelist that contains a line for each unique CVE along with the name of the gate: ANCHORESEC
Eg.
ANCHORESEC CVE-2014-9761
ANCHORESEC CVE-2015-1258
ANCHORESEC CVE-2015-7554
ANCHORESEC CVE-2016-1761
ANCHORESEC CVE-2016-2779
ANCHORESEC CVE-2016-3881
ANCHORESEC CVE-2016-4448
ANCHORESEC CVE-2016-6711
ANCHORESEC CVE-2016-6712
ANCHORESEC CVE-2016-7942
ANCHORESEC CVE-2016-7943
ANCHORESEC CVE-2016-9535
ANCHORESEC CVE-2017-0393
ANCHORESEC CVE-2017-5225
Now if we run the gate analysis passing the whitelist we’ll see a very different result.
# anchore gate --image=nginx:latest --policy=mypolicy --global-whitelist=mywhitelist
+--------------+------------------------+-------+---------+--------------+-------------+
| Image Id | Repo Tag | Gate | Trigger | Check Output | Gate Action |
+--------------+------------------------+-------+---------+--------------+-------------+
| 5e69fe4b3c31 | docker.io/nginx:latest | FINAL | FINAL | | GO |
+--------------+------------------------+-------+---------+--------------+-------------+
The gate command supports a --show-whitelisted flag that shows which allows a user to see which items were whitelisted and from which whitelist.
# anchore gate --image=nginx:latest --policy=mypolicy --global-whitelist=mywhitelist --show-whitelisted
+--------------+------------------------+------------+----------+-------------------------+-------------+-------------+ | Image Id | Repo Tag | Gate | Trigger | Check Output | Gate Action | Whitelisted | +--------------+------------------------+------------+----------+-------------------------+-------------+-------------+ | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libx11-data | | | | | | | | (CVE-2016-7943 - https | | | | | | | | ://security-tracker.deb | | | | | | | | ian.org/tracker/CVE-201 | | | | | | | | 6-7943) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libx11-6 (CVE-2016-7943 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-7943) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libvpx1 (CVE-2017-0393 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2017-0393) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libc-bin (CVE-2014-9761 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2014-9761) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | multiarch-support | | | | | | | | (CVE-2014-9761 - https | | | | | | | | ://security-tracker.deb | | | | | | | | ian.org/tracker/CVE-201 | | | | | | | | 4-9761) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libc6 (CVE-2014-9761 - | | | | | | | | https://security-tracke | | | | | | | | r.debian.org/tracker/CV | | | | | | | | E-2014-9761) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libx11-data | | | | | | | | (CVE-2016-7942 - https | | | | | | | | ://security-tracker.deb | | | | | | | | ian.org/tracker/CVE-201 | | | | | | | | 6-7942) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libx11-6 (CVE-2016-7942 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-7942) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libvpx1 (CVE-2016-6711 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-6711) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libvpx1 (CVE-2016-6712 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-6712) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libxml2 (CVE-2016-4448 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-4448) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libvpx1 (CVE-2015-1258 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2015-1258) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libvpx1 (CVE-2016-3881 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-3881) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libtiff5 (CVE-2015-7554 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2015-7554) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libtiff5 (CVE-2016-9535 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-9535) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | util-linux | | | | | | | | (CVE-2016-2779 - https | | | | | | | | ://security-tracker.deb | | | | | | | | ian.org/tracker/CVE-201 | | | | | | | | 6-2779) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libxml2 (CVE-2016-1761 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2016-1761) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | ANCHORESEC | VULNHIGH | High Vulnerability | STOP | global | | | | | | found in package - | | | | | | | | libtiff5 (CVE-2017-5225 | | | | | | | | - https://security-trac | | | | | | | | ker.debian.org/tracker/ | | | | | | | | CVE-2017-5225) | | | | 5e69fe4b3c31 | docker.io/nginx:latest | FINAL | FINAL | | GO | none | +--------------+------------------------+------------+----------+-------------------------+-------------+-------------+
Whitelisting with Jenkins Plugin
The latest version of the Anchore plugin for Jenkins (version 1.0.9) includes the ability to pass a whitelist file to Anchore to the custom policy file. Using this mechanism you can include a whitelist in the workspace of your project that will be automatically picked up at analysis time.
To update to the latest version of Anchore login to the Jenkins web interface and select:
Manage Jenkins -> Manage Plugins
Press the “Check now button” to ensure that you have the latest plugin metadata.
From the “Updates” tab ensure that you’re upgrading to the latest Anchore plugin - at least version 1.0.9.
To use whitelists within your Jenkins project go to the Anchore Container Image Scanner build step where you will see a similar screen as shown above including the new “Global White list file” entry field.
From this screen press the “Save” button the new setting will not be honored until Save is pressed once.
The upcoming Anchore 2.0 release will support the graphical creation of whitelists and policies along with the ability to define a mapping file that allows the user to define which policies and whitelists are used for any given image based on its registry, repo name and tag.
In our next blog, we’ll dig deeper into advance policy and whitelist options as well as discussing curated whitelists.