Container images are often a key source of vulnerabilities that can be introduced into cloud-native environments. A core part of an effective security strategy is to ensure adherence to secure image-building practices across the organization. While image scanning is an important part of the organization’s security posture, securing images is a way to proactively ensure the security of your containerized applications earlier in the application life cycle.
Adopt the following best practices for creating container images securely:
1. Use minimal base images
The image should contain only the libraries and tools that the container will need to reduce the attack surface.
2. Use base images from trusted sources
If you’re not building an image from scratch, choose base images that come from a trusted source. You should be able to see the Dockerfile and the source code for all of the image components, and it should be hosted in a reputable registry. Base images should also be updated frequently.
3. Specify a user
If the Dockerfile doesn’t specify a user, the container will default to executing with the root user, which both expands the potential attack surface and provides an easy path to privilege escalation if the application is compromised.
4. Verify Docker images
Ensuring image authenticity is a challenge, but it is an important component of building secure images. Any base images should be signed and validated. Only pulling images from trusted registries is a way to ensure all images are authentic.
5. Scan for vulnerabilities
It is important to find and fix vulnerabilities that exist within container images, including those introduced by open-source libraries.
6. Keep secrets out
Secrets, which include sensitive data such as credentials and keys, should not be embedded within container images.
7. Set resource limits
Limiting the amount of CPU or memory resources a container can access helps to restrict the damage it can do if it is used inappropriately.
8. Limit privileges
Set the container’s privileges to be as restrictive as possible and configure the container to make sure that privileges can not be escalated.
9. Use multi-stage builds
The build tools used to generate and compile applications can be exploited when they’re run on production systems. Instead of using the same images in the build and run phase, use multi-stage Dockerfiles to strip any unnecessary complication tools out of the runtime images. Debuggers should also be taken out of production images.
10. Use secure coding practices
These can be enforced by using a linter to catch insecure code during the development process.
While these steps are specific to the image-building process, the principles behind building secure images should also inform security practices in other parts of the application. These practices include keeping the attack surface as small as possible, limiting privileges, and tightening configurations rather than using the default settings in Kubernetes and other aspects of the cloud-native stack.
Last updated: May-31-2020
- Vulnerability scanning - images, in running deployments
- Container image security: beyond vulnerability scanning
- Detecting Docker exploits and vulnerabilities
- Hardening Docker containers, images, and hosts