Deploying applications in containers is increasingly common, but it can pose security risks if not handled properly. A primary container security risk is related to container images, which are templates used to create new containers. Container images can have security vulnerabilities or bugs, and an image passes on its vulnerabilities to all the containers created from it.
Cybercriminals can identify a vulnerability on an image, and exploit it to attack other containers based on that image. Vulnerabilities can enable attackers to compromise the container and applications running on it, steal data, and possibly “break out” of the container to gain control of the host machine.
Container security scanning can ensure that bugs and security vulnerabilities are not carried into production and that vulnerable images are not used to create production containers. Container scanning tools continually audit and scan images and containers. Continuous image security is a key part of a DevSecOps development environment.
In this article:
Here are some of the main types of vulnerabilities affecting containerized systems.
A container image is designed to be immutable. Once you build an image, you cannot change its contents. It is very common for images to contain vulnerabilities, due to the use of outdated packages and libraries. Even if an image uses up-to-date software components at the time it is created, inevitably, the image and its components will at some point become out of date, and will be exposed to security vulnerabilities.
A vulnerability scanner can help identify vulnerable images. While the image cannot be updated, you can fix the vulnerabilities and roll out a new version of the image. You can use this updated image to create new containers going forward.
A common attack vector is privilege escalation. Attackers attempt to escalate privileges to “break out” of a container and gain control of the root operating system.
Privilege escalation attacks exploit vulnerabilities or defects in the Linux kernel or container runtimes. runC is a low-level container runtime that carries out much of the heavy-duty work for containerd, CRI-O, and Docker. In a recent exploit, a compromised container permitted cybercriminals to overwrite host runC libraries and achieve root access to the host of the container.
In a separate example, the outdated Linux kernel vulnerability CVE-2017-7308 was used to modify the existing process’s namespaces into those of process 1, as well as the host’s namespaces. This was done by requesting a Linux kernel system call, which enabled an escape to the host.
Cryptojacking attacks use malicious scripts to steal the computational resources of a device. The goal is to use stolen resources to mine cryptocurrencies. This type of vulnerability can affect a variety of technologies, including containers.
For example, a Docker vulnerability, referenced as CVE-2018-15664, enables attackers to gain root access to the host of a machine, letting attackers use the CPU and GPU resources of the host to mine crypto. It also lets attackers steal sensitive credentials, launch phishing campaigns, and carry out Denial of Service (DoS) attacks.
Malicious container images can provide threat actors with root access to an entire container. Additionally, if a Docker container API endpoint is publicly accessible across the internet without any password protection or security firewalls, it may also be vulnerable to attacks.
Here are several types of container security scanning technologies:
Image scanning processes analyze the contents as well as the build process of each container image. The goal is to detect vulnerabilities, bad practices, and security issues. Here are several best practices that can help you effectively scan container images.
Related content: Read our guide to general container security best practices
Applications often use a vast amount of libraries, which may add up to more lines of code than those created by your team. Be sure to scan for vulnerabilities not only in your code, but also in all dependencies. If you are using a scanner that scans third-party libraries, you can use it to track vulnerabilities in libraries using the same feeds employed to warn about operating system vulnerabilities.
Related content: Read our guide to container security tools
Be extremely careful when building container images and scan each image before publishing it. To ensure efficiency, you can add image scanning into your CI/CD pipeline as another phase in the cycle. Instead of directly publishing your image to production once it is built, you should push it to a staging repository and then run your image scanner.
A container security scanner can provide a report that details all detected issues, while assigning specific severities to each one. Use your CI/CD pipeline to check the results of the image scanning process. If there are critical issues, you can simply fail the build—before it reaches production. You can automate the container scanning process to ensure you catch vulnerabilities before any can enter the registry or production.
Strive to build the lightest possible image. The lighter the image, the faster your builds and scans. As a result, the image also has fewer dependencies that may contain potential vulnerabilities.
Typically, new Docker images are built by using, or adding a layer over, an existing base image. A base image is defined through the
FROM statement located in the image Dockerfile. This process creates a layered architecture design, which saves a significant amount of time.
However, if you scan a base image only once and the parent image is vulnerable—any other images you build on top of it remain vulnerable, too. To mitigate this issue, use scanning tools to actively track vulnerability feeds for any known vulnerable images. The tool will let you know if you are using any of the known vulnerable images.
Distroless images are base images that do not contain shells, package managers, or any programs running in a standard Linux distribution. A distroless image lets you package only the application and its dependencies within a lightweight container image. Essentially, it enables you to restrict what is allowed within your runtime container and minimize the attack surface.
To optimize container images, pay special attention to the
RUN commands in your Dockerfile. The order of your
RUN commands significantly impacts the finalized image, because it determines the order of the layers that make up the image.
To optimize your Docker cache usage, you can place bigger layers (typically invariant) first, and place the most variable files (the compiled application) at the end. This helps prioritize reusing existing layers, accelerate image building, and also indirectly speed up the image scanning process.
Calico Cloud offers active build, deploy and runtime security for containers and Kubernetes.
Visit our container security solutions page to learn more about Calico Cloud’s container security features.
Get updates on blog posts, workshops, certification programs, new releases, and more!