How Many CVEs?

For most users analyzing or auditing container images usually means running a CVE scan and while that is certainly required, it should be just the first step. Anchore supports creating policies that can be used to assess the compliance of your containers, these policy checks could cover security, starting with the ubiquitous CVE scan but then going further to analyze the configuration of key security components, for example, you could have the latest version of the apache webserver but have configured the wrong set of TLS Ciphers suites leading to insecure communication. Outside of security, policies could cover application-specific configurations to comply with best practices or to enable consistency and predictability.

Today there are many tools that can perform CVE scans of a container image however when we speak to users we often hear that either they do not perform these scans or if they do they do not gate container deployments based on the results of these scans. When we asked these users why they didn’t stop their deployment based on the CVE scanner’s results, we were told “if we did then we’d not deploy any containers – they all fail!

This is a common issue, for example, if you look at the official images on Docker Hub or Docker Store for CentOS, Debian, Oracle or Ubuntu they all appear to have high or critical vulnerabilities many of which are unfixed, some appear to be CVEs that are unresolved for over a year or more.

We have covered this topic previously with respect to CentOS where we saw many vulnerabilities reported by other tools in the CentOS image that were not accurate and similar issues with Oracle and RHEL images.

It has been pointed out that Debian, which as we discussed in our previous blog, is the most popular operating system used on Docker Hub seems to have the most vulnerabilities. Regardless of the CVE scanner used, the Debian image looks insecure with many unpatched vulnerabilities, but looks can be deceptive.

We will take a look at the Debian image and discuss the results found by various scanners, explain the differences in results and show how you can remove the noise and get a clear view of the security of your containers.

Which Package is Vulnerable?

Let’s start by looking at a vulnerability reported in the latest Debian image: CVE-2017-12424 which describes a vulnerability in the shadow project which provides tools and libraries for maintaining the password database.

Looking at the output of most of the CVE scanners you will see output similar to the following:

Here we can see that shadow version 4.4-4.1 is installed and vulnerable to the critical severity CVE 2017-12424. But if you look for the shadow package in your image you will not find it.

root@debian:/# dpkg -s shadow
dpkg-query: package 'shadow' is not installed and no information is available

So if you try to upgrade that individual package you’ll receive an error.

Debian reports CVEs against source packages rather than against binary packages so in this example while the source package was shadow the binary package is called passwd.

You can look up the source package for a given binary package either using the dpkg utility or using apt-get source.

root@debian:/# dpkg -s passwd | grep Source
Source: shadow

This example using the shadow package is rather straight forward, I would expect that most readers of this article would quickly work out the mapping to the passwd binary package however in many other cases things are not so simple. For example, many non-kernel binaries are created from the Linux source package this leads to some tools reporting kernel CVEs in a container image that includes no kernel.

For this reason in the Anchore Cloud and Anchore Engine both report on the binary package not the underlying source package.

How Many Vulnerabilities?

Analyzing the same image with different scanners often results in very different numbers of reported vulnerabilities. In some cases, as we described in a previous blog, this may be a result of the scanner not taking into backporting of fixes, or not using distribution’s own security vulnerability feed. In other cases the mapping of CVE to source and image package causes confusion. For example, looking at the current debian:latest image using Anchore’s scanner we can see eight packages are shown as being vulnerable to the vulnerability described in CVE 2016-2779.

This CVE was reported against the util-linux source package. The binary packages listed in this report are all built from the util-linux source package. A tool, such as Anchore, that reports on binary packages will report seven packages against that CVE while a tool that reports on source packages may only report one. Whether one or all of these binary packages are vulnerable to the vulnerability described in the CVE is something that requires digging deeper into the bug reports and mailing list traffic. Ideally, the distributions would provide more binary specific details in the vulnerability data to assist in this mapping.
A more interesting question is: if even one of these packages was vulnerable why after nearly 18 months are fixes not available for these packages? We need to dig deeper.

Is it Really Vulnerable?

As we saw in the previous example we often see unfixed CVEs in images. For example in the current debian:latest image we see 50 vulnerabilities that have no fixes and 12 of these are rated as High severity.

Even if we just counted the number of unique CVEs, not packages, we still see: three high, three medium, one low and 15 Negligible CVEs.

Why is that number so high? Since this is the latest official Debian image there is certainly more to this, especially given the fact that the Debian security team are renowned for their focus and responsiveness.

We can start by looking at the CVE in Debian’s security tracker: CVE-2016-2779. Here you can see that the current stable version of Debian, stretch, is classified as being vulnerable, however, looking in the notes section we see the following:

The security team notes that no Debian Security Advisory will be issued for this vulnerability (no-dsa). You can read more about this on the Debian Security FAQ here, however, the concept here is that while a source package may be vulnerable the way that it is compiled or deployed may mitigate the issue. In some cases, this may be because the package is built with specific compile-time options that don’t trigger the security issue in other cases this may be due to the environment in which it is run. In this specific case, it was decided that the best approach was to address the underlying issue in the Linux kernel so that no version of this package could trigger the vulnerability.

Based on this data we should not be concerned about this high criticality CVE in our scan results. There is certainly an argument to be made that given this fact maybe this CVE should not be reported in the Debian vulnerability feed, which is the approach that the Red Hat-based distributions such as CentOS, Oracle and RHEL take. I have not looked into the history around this decision but can imagine the strong arguments to be made on both sides. Presumably anticipating this issue, the Debian team includes metadata in their vulnerability feed that indicates the No Debian Security Advisory decision and commentary. This is data we can then use as part of our analysis of the image.

Looking at the current debian:latest image using Anchore Cloud we can view the image’s policy status to see if it PASSES or FAILES based on the default image policy.

Here we can see that the image has failed, scrolling down we can see 12 High criticality vulnerabilities that led to this result. You can read more about the image policies here.

Anchore includes support for whitelists which allows for certain policy checks, such as select CVEs, to be suppressed. A CVE may be present in a package but not exploitable in that package’s configuration as we saw earlier in this blog. So using the Anchore policy editor a user can create and manage whitelists to filter out false positives.

Whitelists can be created and managed in the policy editor or from the image’s policy view but in the case of Debian security advisories it is easier to create a whitelist and upload into the Anchore Cloud.

We have published a simple utility that creates whitelists based on the data published in the Debian security tracker. You can clone this utility from our public GitHub repository.

git clone

Running the debian-whitelist.py utility will create a JSON document for each of the current Debian releases: Wheezy, Jessie, Stretch and Buster (which right now has no whitelisted CVEs).

1. Create a free account on the Anchore Cloud

2. Open the Policy editor by selecting the menu icon on the left navigation menu.

3. Expand the Whitelist editor

4. For each whitelist press the “Upload Whitelist Item” button and upload the JSON document. The whitelists will be named based on the version of Debian and the date. These names can be edited to be more user friendly.

You will now have whitelists for each Debian version.

Next, we need to use the Mapping Editor to define what whitelist is used for a specific image.

5. Expand the Mapping Editor

6. Select “Create New Mapping” to create a new mapping.

7. Give your mapping a name, eg. “Debian latest”

8. Specify library/debian as the repository name

9. Specify latest as the tag

10. Select the whitelist you created from the dropdown.

11. Select “Save All” to save the whitelist and policy mapping.

Now when you view the Debian image you will see that a user-defined policy has been used and that the image passes.

The whitelists CVEs can be viewed by checking the Show Whitelisted entries checkbox.

Currently, Anchore only applies the whitelist to the policy view and not to the list of CVEs presented in the security tab which shows all CVEs present in the image.

By using the default policy we are just performing basic CVE policy checks on the image but using the policy editor you can create policies that do much more.

Anchore Cloud 2.0

Today Anchore announced the release of Anchore Cloud 2.0 which builds on top of Anchore’s open source Engine to provide a suite of tools to allow organizations to perform a detailed analysis of container images and apply user-defined policies to ensure that containers meet the organization’s security requirements and operational best practices.

Anchore released the Anchore Navigator back in October 2017 and since then thousands of users have used the service to search for container images, perform analysis on these images and sign up to receive notifications when images were updated.

The Anchore Cloud 2.0 release adds a number of exciting new features for all users and a new paid tier which offers support and added features for subscribers.

Graphical Policy Editor

The new graphical policy editor allows all users to define their own custom policies and map which policies are used with which images. These policies can include checking for security vulnerabilities, package whitelists, blacklists, configuration files, secrets in image, manifest changes, exposed ports and many other user-defined checks. The policy editor supports CVE whitelisting – allowing a curated set of CVEs to be excluded from security vulnerability reporting.
Using the policy mapping feature, organizations can set up multiple different policies that will be used on different images based on use case. For example, the policy applied to a web-facing service may have different security and operational best practices rules than a database backend service.

Anchore policy editor view

Private Repositories

Subscribers can configure the Anchore Cloud to scan and analyze images in private repositories stored on DockerHub and Amazon EC2 Container Registry (ECR).

Once configured the service checks for changes to the repository approximately every 15 minutes. When a change is detected, for example, a new image is added to the repository or changes to tags, Anchore will download any new images, perform deep inspection and evaluate the images based on the policies defined by the user.

Anchore registries editor view

Notifications

Previously the Anchore Cloud allowed users to subscribe to a tag and be notified when that tag was updated – for example when a new debian:latest images were pushed to Docker Hub.

For subscribers, the Anchore Cloud can now alert you by email when CVEs have been added or removed from your image and when the policy status of your image has changed, for example, an image that previously passed is now failing policy evaluation.

Example of Anchore notification

On-Premises Integration

Anchore Cloud supports integration with Anchore’s open-source Engine for on-premises deployments, allowing the policies defined on Anchore Cloud service to be applied to images created and stored on-premises.

Anchore Cloud supports integration with CI/CD platforms such as Jenkins, allowing containers built in the cloud or on-premises to be scanned as part of the CI/CD workflow ensuring proper compliance prior to production deployment.

More Than Just Security Updates

In our last blog, we talked about how quickly different repos respond to updates to their base images. Any changes made by the base image will need to be implemented in the application images built on top of it, so updates to popular base images spread far and, as we saw from the last blog, quickly.

The only type of update we have covered so far in this series of blogs is security updates. However, that is only one part of the picture; package updates may contain non-security bug fixes and new features. To gain some insight into what is being changed in these updates, we have broken down exactly what packages change for a few of the more popular operating system images.

One interesting time to look at package differences is when the operating system gets updated to a new version.

 

Centos 7.4 overview in Anchore

Looking at the overview tab for library/centos:latest, when it just got updated to version 7.4, the Navigator shows in the chart on the righthand side that there were many changes with this update. Shown below is a breakdown of which packages have been updated since last September. Only a portion of the packages are shown, you can find the rest in the link below.

Focusing in on just that most recent update, we see that 80 of the 145 packages have been updated. The image from Sep 13th was CentOS 7.3, while the one from Sep 14th is CentOS 7.4. Looking into some of the changes, bash, like many others, received backports of bug fixes. Other packages were new additions, such as elfutils-default-yama-scope, while one, pygobject3-base, was removed from the image. In terms of CVE/Security updates, this was an ineffectual update; a quick check of the security tab of both versions (7.3, 7.4) shows that there were no changes in CVEs between the two.

Click the button below to access the full spreadsheet with all package updates for 6 popular operating systems.

View the Full Spreadsheet

In the spreadsheet, you’ll see Alpine stands out in terms of image size and reduced package count. Having more packages means having more packages to maintain. Even if Alpine were to update almost all of its 11 packages, as it did on May 25th, there would not be as many changes as a standard Debian update, such as the one on June 7th, where 25 of 81 packages were updated. There is a trend towards lightweight images, and the appeal of simpler updates might be one reason behind it. Among public repositories, Alpine is growing its share of usage as a base image. Other base operating systems are beginning to including slim versions of their containers, such as Debian, which has a slim version of each of its releases as well as Oracle and Red Hat.

Comparing the sizes of the two Debian tags included in the spreadsheet, stretch and stretch-slim, we see that the slim version is about half the size of the original, 95 MB vs 53 MB. The trend goes across releases too; Debian Stretch (Debian 9) images are around 90 MB while Jessie (Debian 8) images are around 120 MB. Ubuntu 16.04 is around 120 MB while 17.04 is around 90 MB. One repository not slimming its images is CentOS. It does not currently include slim versions, even though Red Hat Enterprise Linux, from which CentOS is based, has a slim image known as RHEL Atomic.

Part of slimming down containers is removing packages that are not necessary. In some instances, packages are included that are arguably not required in the context of a container, such as device-mapper or dracut. This harkens back to a previous blog, where we discussed how containers are often being used as micro-VMs rather than microservices. The packages listed above, among others, lend themselves to running a full machine, rather than running just a single application. Removing these extra packages is not as simple as it initially appears. For example in the CentOS 7 image dracut, which builds initramfs images to boot an OS, is pulled in as a requirement by kmod, which provides an infrastructure for kernel module loading, which is pulled in by systemd. We see many similar examples in the traditional Linux vendors’ images, where the package management system was designed before the advent of containers. This is a topic we will revisit in a future blog.

Even though smaller base images require less maintenance and storage, having fewer packages means less functionality. Most application images built on top of Alpine require that users add many more packages onto the base image so application images are often significantly larger than the 4MB base image. But having the choice to add to an image rather than working out how to remove packages certainly simplifies maintenance for the developer and allows for a reduced attack surface. In our next blog, we will look at some popular application images that are available based on multiple distributions to see how the image size, bug count and update frequencies compare.