Vulnerability: runc process.cwd and leaked fds container breakout (CVE-2024-21626)
January 31, 2024
0 mins readSnyk has discovered a vulnerability in all versions of runc <=1.1.11, as used by the Docker engine, along with other containerization technologies such as Kubernetes. Exploitation of this issue can result in container escape to the underlying host OS, either through executing a malicious image or building an image using a malicious Dockerfile or upstream image (i.e., when using FROM
). This issue has been assigned the CVE-2024-21626.
How does CVE-2024-21626 work?
Demo 1: Container breakout via docker build
. What you’re seeing here is the exploitation of docker build
to break out of the container and access the host filesystem via an arbitrary read (in this example, the host’s /etc/shadow
file) and write (in this example, the creation of a DOCKER_BUILD_BREAKOUT
file).
Demo 2: Container breakout via docker run
. What you’re seeing here showcases how running a malicious Docker image based on the same vulnerability can similarly result in the breakout of the Docker container to the host OS.
The vulnerability occurs due to the order of operations when applying the WORKDIR
directive defined in the Dockerfile. WORKDIR
defines the initial working directory of all processes created by the Dockerfile, such as those executed at build-time using the RUN
directive and those executed at run-time using the CMD
or ENTRYPOINT
directives. The provided directory is entered using chdir
before specific privileged host directory file descriptors have been closed. It is possible to specify one of these privileged file descriptors via the /proc/self/fd/
directory as the argument to chdir
, which causes the privileged file descriptor to remain accessible even after the file descriptor itself is closed during normal operations, prior to handoff to the Dockerfile defined command, either at build or runtime.
In a successful attack, the now-executing process ensures that the current directory is a host directory and traverses the host directory structure to access the full host root filesystem. By default, access privileges will be the same as that of the in-use containerization solution, such as Docker Engine or Kubernetes. Generally, this is the root user, and it is therefore, possible to escalate from disk access to achieve full host root command execution.
How to mitigate CVE-2024-21626
runc mitigated this vulnerability by ensuring the directory specified in the WORKDIR
directive is present in the container root filesystem. runc also implemented additional hardening steps to ensure the privileged host directory file descriptors were appropriately closed immediately after use.
Snyk recommends taking immediate action following the runc advisory to mitigate this security vulnerability. The runc 1.1.12 release includes patches for this issue. Technologies that bundle runc should also be updated to their respective patched versions, and vendor advisories should be followed/implemented where hosted solutions are in use (such as managed Kubernetes services from popular cloud providers).
Evaluating risk
This vulnerability depends on a malicious container running or building within a vulnerable infrastructure. Due to the nature of this vulnerability, detection is difficult and requires runtime for the most accurate detection. As our existing Snyk products don’t operate on the application runtime, we built two tools to make the detection of this vulnerability feasible.
Runtime detection
The new Helios team at Snyk has built an an eBPF-based runtime detection tool for this vulnerability, which can be found at leaky-vessels-runtime-detector, released under the Apache-2.0 license. eBPF is a commonly used instrumentation mechanism built into many modern Linux kernels.
This tool can identify a running container attempting to exercise this vulnerability on underlying infrastructure, placing the underlying host at risk. Note that this tool cannot prevent the exploitation of this vulnerability, only warn of exposure.
While updating your container infrastructure is our strong recommendation, you may be able to evaluate your risk or exposure using this tooling when updating is not immediately possible. Organizations should check with their container infrastructure provider to understand whether its infrastructure has been patched.
Installation and usage
To install and use our static detection tool, please do the following:
Clone the repository at https://github.com/snyk/leaky-vessels-dynamic-detector
Build the Go binary with
go build
.Run the detector in your CI environment with:
sudo ./ebpf-detector
For additional details, please check the README.md file.
Static analysis
In case you prefer not to run an external binary on your host or CI/CD pipeline, we’ve also built a static analysis detector, found at https://github.com/snyk/leaky-vessels-static-detector, that analyzes Dockerfiles and flags potential exploit attempts.
This tool examines images by parsing the FROM
instruction or directly querying the local Docker daemon or public container registries like Dockerhub or GCR. Although the image history doesn’t include all the instructions a full Dockerfile would, it shows the WORKDIR
and ONBUILD
instructions of the parent image, which can indicate potentially nefarious images.
This is useful to protect against cases where a 3rd party base image has been compromised and tries to exploit the run
or build
commands of the child image. The static approach has a higher false positive (noise) rate, especially for exploits using the --mount flag
, but can find images worthy of further investigation.
The Snyk team has performed ad hoc checks of Dockerfiles from public registries based on the images we see being used most frequently. While not exhaustive, our research did not find evidence suggesting that these vulnerabilities have been exploited. Snyk recommends that you continue monitoring your own environment and check your containers until patches are made available and deployed.
As always, using well-maintained parent images from trusted sources and staying up-to-date with the latest versions — including clearing out build caches and verifying the provenance of parent images — is a good best practice.
Installation and usage
To install and use our static detection tool, please do the following:
Clone the repository at https://github.com/snyk/leaky-vessels-static-detector
Build the Go binary with
go build
.Run the detector with:
./static-detector dockerfile -f [PATH_TO_DOCKERFILE].
For additional execution options, please check the README.md file.
CVE-2024-21626: Summary and advice
This container breakout vulnerability is severe and has the potential to cause damage to any underlying host infrastructure that is either running or building containers.
Snyk recommends you update any instances of runc to version 1.1.12 or later, as well as any software that depends on runc. In addition to this, please ensure you’re following any vendor advisories related to this issue, as container hosting services and infrastructure may be impacted.
Snyk has also disclosed several other container breakout vulnerabilities in our research, assigned CVEs: CVE-2024-23652, CVE-2024-23651, and CVE-2024-23653. You can read the summary of our findings across all the CVEs here.
This article is provided for informational purposes only. Snyk is not responsible for any errors or omissions, or for the results obtained from the use of this information.