How to Detect Vulnerabilities in Docker Images
By: Al-Waleed Shihadeh
Tags: Docker, Cybersecurity, Containers, Programming, DevOps

How to Detect Vulnerabilities in Docker Images

Improve the security of your Docker containers

Photo by camilo jimenez on Unsplash

Clair is an open source project for the static analysis of vulnerabilities in application containers.

One of the main differences between a traditional deployment and a Docker deployment is the way that software dependencies are handled. In traditional deployments, the software dependencies need to be installed and managed by a dedicated team. They install required versions of dependencies, upgrading them when security issues arise, and performing regular patches to the operating system packages. Managing and installing all the dependencies on the hosts and resolving dependency conflicts between different software on the same server is a challenge and time-consuming.

Docker deployments solve these challenges by encapsulating all the needed dependencies for a given software within its own Docker image. These dependencies are installed during the Docker build time and are only applicable for the containers running with the generated Docker image (these dependencies do not also affect the host). However, since Docker images consist of multiple layers, starting from the OS (ubuntu, alpine, centos, etc) to the application layer itself, there’s a risk that the Docker images will include vulnerabilities that could expose some security risks and provide the attackers with ways to gain access to the hosting servers.

According to the National Vulnerability Database, there are more than 75,000 known vulnerabilities. Some of these vulnerabilities are well-known, like Heartbleed which affected OpenSSL. This means that there’s a high chance that the Docker images used to deploy the applications include some of these vulnerabilities. Obtaining this information requires scanning Docker images and perform analysis and comparison against known vulnerabilities. Unfortunately, this feature is not available in both the Docker registry and Portus so another tool is needed to achieve this goal.

Clair is a tool that can be used to scan Docker images and report any vulnerabilities found. Clair exposes an API for indexing docker images and queries the database for vulnerabilities of a particular image. Before we jump into deploying Clair and integrating it with Portus, let’s have a quick look at how Clair works:

Clair periodically pulls external databases and updates its internal database with known vulnerabilities.

Clients (Registry or Portus) send images to Clair API to be analyzed.

For performance and efficiency reasons, Clair analyzes Docker images layer by layer and not on image bases. This is because Docker images share layers and there’s no need to analyze the same data/layer more than once.

Clair passes the image layers to workers to detect vulnerabilities in each of the layers. Three different detectors for finding vulnerabilities in Docker image layers are supported by Clair.

The first type is the Data Detector , which is responsible for scanning the layer for any static configurations that should not be included in production. The second type is the Feature Detector , which basically can be anything in the Docker container, from packages like OpenSSL to configuration parameters. The last detector is the Namespace Detector . This detector is based on the context between features and vulnerabilities . This detector is able to find issues like installing a centos6 package on centos7 .

Clair deployment

As described above, Clair stores the data collected about the Docker images in an internal database (PostgreSQL database). Therefore, we need access to an HA PostgreSQL database to perform the deployment in production environments. For the sake of simplicity, I will deploy a PostgreSQL server with the Clair Docker stack (this is also can be done in testing environments).

To avoid using Docker volumes for the Clair service I decided to build a custom image that includes a configuration template and can be configured using environment valuables. Here’s the Dockerfile for the custom docker image:

Clair Dockerfile

And here’s the entry-point file that takes care of rendering the template and generate the config file for Clair:

Clair Entry-point

Finally, here’s the Docker swarm stack I used to deploy Clair and its dependencies:

Clair Docker Stack

After deploying the Clair stack (Clair server and PostgreSQL database) the next step is to integrate Clair with Portus to be able to scan Docker images. By default, Clair exposes its API on port 6060 . As a result, to integrate Clair with Portus we need configure Portus with the Clair URL, which will be something like this: http://clair_server:86060 . We need to add this value to the environment variables PORTUS_SECURITY_CLAIR_SERVER , or by updating Portus configs.

After integrating Clair with Portus and push some images to the Docker registry, we can start seeing vulnerabilities reports, as shown below: