Securing Docker Containers with Chainguard
This is a story of hacking containers not due to the lack of security best practices, or vulnerable dependencies of Node.js applications, but that of third-party open-source components which may exist in a Docker-based Node.js application.
1. I have created a single-page node web application that allows a user to upload any image file and resize the image by clicking on the “resize” button.
2. I’m using the traditional docker image: FROM node:6.1.0
3. The reason why I’ve selected the old version of node is to demonstrate the CVE-2016-3714 – Insufficient shell characters filtering leads to(potentially remote) code execution.
If the user uploads any random.jpg image with the following contents:
push graphic-context viewbox 0 0 640 480 fill 'url(https://127.0.0.0/oops.jpg"|touch "rce1)' pop graphic-context
The file with name “rce1” will be created in the web root of the docker. (RCE)
Basically what I did was: turned the ImageTragick security vulnerability (https://imagetragick.com/) in the version of ImageMagick that exists in the container image into a remote command injection attack.
The attack we demonstrated here completely bypasses all secure coding conventions and goes beyond the security of the Node.js runtime or the open source node modules dependencies that the application bundles. This really emphasizes the need to secure our Docker images.
Next, we’re going to scan this image using docker scout.
Now we’re going to rebuild the container using chainguard’s secure image and then observe a significant drop in the number of potential CVE’s that were present in the original image.
In addition to this, we can also see some of the security measures that are present by default in chainguard images such as:
– The default user in a docker container built using chainguard is non-root user
– Significant drop in the image size.