Since its introduction in 2013, Docker has grown into a massively popular solution for deploying applications. By allowing applications to run inside isolated environments called containers, while at the same time avoiding the extensive resource overhead associated with virtual machines, Docker provides portability and security benefits without significantly reducing system efficiency.
But the isolation that Docker provides between containers doesn’t protect against all types of security risks. On the contrary, a variety of vulnerabilities can lurk inside Docker images, which are the “blueprints” on which Docker containers are based. Key examples include:
- Malware that attackers inject into Docker containers alongside legitimate applications. The injected malware will be executed along with the rest of the container.
- Networking configuration risks, such as leaving insecure ports open using the EXPOSE instruction in a Dockerfile. Attackers could abuse these ports to gain access to an insecure container. They could then potentially use that beachhead to escalate the attack to the rest of the system.
- Identity and Access Control (IAM) configuration risks that allow containers to access external resources that shouldn’t be available to them.
- Exposed credentials (ex. API keys) inside the docker image, which can be reused by any attacker that has access to the image or the container.
- Images infected with a privilege escalation attack that manages to break out of the container and into the host — such as an image that runs a kernel privilege escalation exploit on its entrypoint.
Using Docker image scanning to secure Docker
Docker security scanning is the primary method of detecting risks like these inside Docker images. Docker image scanning tools automatically scan all layers of Docker images to check for malware, misconfigurations and other risks that could lead to a security breach within a Docker-based application environment.
Docker image scanning works by identifying the contents of a Docker image, then checking whether the contents match components that are known to be insecure. For example, Docker image scanning tools might discover that a certain open source library within a Docker image contains a known security vulnerability. Docker image scanners that can scan configurations in addition to the application contents of an image are also capable of detecting misconfigurations that could invite security problems, such as the networking or IAM issues described above.
The limitations of Docker image scanning
While image scanning is one essential part of a Docker security strategy, it’s important to understand that image scanners don’t address all types of potential Docker security risks.
Docker image scanning won’t detect risks such as:
- Misconfigurations with container orchestration tools, like Kubernetes, which attackers could use to gain access to a containerized application environment.
- Security vulnerabilities that exist within the operating system used to host containers.
- Security risks that arise from proprietary application code or libraries that are not included in the vulnerability databases used by Docker security scanning tools.
Best practices for Docker image security
When building and deploying Docker images, teams can help to mitigate the risk of security vulnerabilities that originate from insecure images by adhering to a set of Docker image security best practices, including the following.
Scan all images
A basic best practice is to scan all Docker images prior to running containers based on them. Scanners can detect risks like components that are known to be subject to security vulnerabilities, or configuration issues that may lead to security problems.
An easy way to perform scanning is to integrate image scanning into your Docker container registry so that images are automatically scanned whenever they are uploaded to your registry. Image scanners like JFrog Xray can integrate with container repositories like Artifactory for this purpose.
Avoid the :latest tag
When downloading Docker images from a container registry, you can use the “:latest” tag to download the most recent image version available in the registry. This is convenient, but it’s not ideal from a security perspective because it could result in the deployment of a different version of the application from what you expect. For example, you may inadvertently deploy a beta version of a container that has security issues.
While Docker image scanning should protect you from insecure images even if you use the :latest tag, it’s a best practice to avoid this tag. Instead, specify the image version you want to use.
Avoid unnecessary image contents
When you build a Docker image, stick to the principle that less is more. In other words, the fewer layers you include in a Docker image, the better from a security standpoint. Choose base images (which serve as the foundation for new Docker images) that contain only components that are strictly necessary for your application, and avoid adding libraries or commands to the image that you don’t need. Base images like Alpine Linux, a lightweight Linux distribution, are popular for this purpose.
Protect your container registry
Anyone who has access to your container registry can potentially upload insecure Docker images to it. They may also be able to disable image scanning, leaving you unprotected against malicious images.
Prevent these risks by choosing a Docker registry that allows you to configure granular access controls so that each user can access or modify only the specific images he or she needs. You may also consider using a private Docker registry, which can only be accessed from the network endpoints and/or users you specify, instead of a public registry, which is visible to the world at large.