Docker image security requires a layered approach

Scanning for vulnerabilities in software components has become one of the most important aspects in software development.

Whenever we consume a component, it’s crucial to the release process for us to ensure that it does not introduce any kind of a security breach or vulnerability.

Whether we are using Maven, NPM or any other technology, it is essential to scan our components. This is especially true for Docker images that contain multiple layers which could introduce multiple vulnerabilities. In this article, we will focus on the importance of scanning all the layers of Docker images.

What is a security vulnerability?

Loosely defined, a security vulnerability is a weakness that exposes our software to unauthorized access to information, and/or to unauthorized activity. For example, SQL injection can be used to expose the contents of your database to an attacker, and code injection can be used to change how a program executes. There are many other types of security vulnerability that can be exploited in our software if we’re not careful.

What are Docker image “layers”?

When we deep dive into how a Docker image is built, we can see that it contains a series of layers which Docker eventually combines into a single image. The “Dockerfile” specifies a base image (this is a requirement of Docker) and a set of instructions such as FROM, RUN, MAINTAINER,  COPY, and more. Each instruction adds a layer to the previous image resulting in a new image.

Why isn’t it enough to scan just the base image?

That might be convenient and make your image scanning process quicker, but it does not provide the protection you need. As each layer is added to an image, new software components are used, and each of those has the potential to introduce vulnerabilities

To eradicate vulnerabilities and prevent contamination of your software, you need to recursively scan all layers of the images in all your private and public Docker registries to weed out vulnerabilities in every layer.  And since a component may be reused in several Docker image layers, once a vulnerability is detected, you would want to run an impact analysis to find all the layers in which that component is used, whether those layers are in the same Docker image in which the vulnerability was found, or in different ones. And then, you would also want to know if there is a newer version of the infected component that you could use in the contaminated Docker image layer to remediate the vulnerability. Only a layered approach can point you in that direction.

It doesn’t end with security vulnerabilities

While the term “vulnerability” is normally associated with security breaches such as exposing sensitive data, or running unauthorized code, there’s something else to consider. Many of the software components used in your  Docker images will be open source software, and will come with a license that is binding to your company. You need to make sure that all of the open source components used in any layer of your Docker images, and their corresponding licenses, are approved by your company’s policies.

Shift your layered protection left

It’s well known that the cost of fixing a bug rises dramatically the later the bug is found. Fixing a bug found in production systems can cost as much as a hundred times as the cost of fixing a bug during design or development.

Well, for all intents and purposes, a security vulnerability or open source license issue in a component of one of your Docker image layers is, effectively, a bug. It needs to be remediated, and the earlier the better.

Therefore, you should add a scan cycle for your Docker images during the CI process that builds the layers. A scanning tool that integrates with your CI server could detect vulnerabilities relatively early in your Docker image’s life cycle and make the remediation efforts much easier to manage. You could be lenient with your policies and issue alerts to the right administrator, or you could enforce strict policies that would break any build in which a component with a vulnerability was discovered in any of your Docker image layers.

Protecting your layers is mission-critical

I think we have established the importance of scanning each and every layer of your Docker images. Now, I want to take this a step further and assert that security vulnerability protection is mission-critical to your business. The costs of remediating security vulnerabilities can be anything from unpleasant to downright life-threatening for a business.

So you need to make sure your security scanning tool is always running, scanning layers of your Docker images from build to production. The best way to ensure that is to use a scanning tool that supports high availability. High availability is obtained when your scanning tool runs a cluster of multiple concurrent and synchronized instances using shared data.

That way, if any of the instances goes down abruptly (yes, s**t happens), or needs to be taken down for maintenance, the rest of the instances in the cluster can absorb the load and keep your systems running. Protection and scanning of your Docker images continues uninterrupted until the downed instance is brought back into operation.

Your layered approach should also be universal

Between the base layer and the application layers, a Docker image may typically include infrastructure components such as operating systems and databases, while the application layers may include software packages developed with different technologies. To provide protection for all of these layers, you need a universal scanning toolthat can detect issues and vulnerabilities in all the technologies you use.

Like the paradigm of the chain and link, a Docker image is only as secure as its most insecure layer. That’s why you need to ensure that each and every layer of your Docker images are all scanned for security vulnerabilities and license compliance issues, as early in the application life-cycle as possible, to ensure that once your images are in production, they’re vulnerability and issue-free.