A container escape vulnerability lets a process break out of its container's isolation boundary and gain access to the host operating system, other containers, or the underlying cloud infrastructure. On February 11, 2019, researchers Adam Iwaniuk and Borys Popławski disclosed CVE-2019-5736, a flaw in runc (the low-level runtime used by Docker and Kubernetes) that let a malicious container overwrite the host's runc binary and execute code as root on the host. Five years later, on January 31, 2024, Snyk researcher Rory McNamara disclosed CVE-2024-21626, dubbed "Leaky Vessels," affecting runc versions up to 1.1.11 with a CVSS score of 8.6. Container escapes are not theoretical edge cases — they are recurring, high-severity CVEs in the exact runtime components that every containerized workload depends on.
What is a container escape vulnerability?
A container escape vulnerability is a flaw that allows code running inside a container to access resources outside the boundary the container runtime is supposed to enforce — the host filesystem, host processes, the kernel, other tenants' containers, or the cloud metadata service. Containers are not virtual machines: they share a single Linux kernel with the host, and isolation is enforced by kernel features like namespaces, cgroups, and capabilities rather than hardware-level virtualization. When a bug exists in the container runtime (runc, containerd, CRI-O), in a misused kernel feature (cgroup release_agent, /proc, symlink handling), or in a misconfiguration (privileged mode, mounted host paths, shared PID/network namespaces), that shared-kernel model becomes an attack surface. The practical impact ranges from reading secrets mounted into other pods to full root code execution on the underlying node, which in a Kubernetes cluster typically means compromise of every workload scheduled on that node.
How does CVE-2024-21626 ("Leaky Vessels") allow escape from a container?
CVE-2024-21626 allows escape because runc leaks an open file descriptor pointing to the host filesystem (/) into the container process during the WORKDIR or startup sequence. An attacker who controls a Dockerfile, a base image, or a docker exec session inside a container can reference that leaked file descriptor — typically via /proc/self/fd/<N> — to open a path traversal into the host's root filesystem, bypassing the mount namespace entirely. The disclosure bundled three related CVEs (CVE-2024-23651, CVE-2024-23652, CVE-2024-23653) affecting BuildKit and Docker Desktop, because the same leaked-fd pattern showed up in multiple build and runtime code paths. The fix landed in runc 1.1.12, released the same day as disclosure, and Docker Engine 25.0.2 and BuildKit 0.12.5 shipped corresponding patches. Any organization still building images with an unpatched BuildKit or running an unpatched runc after January 31, 2024 was exposed to a real, exploitable escape rather than a theoretical one — Snyk's proof-of-concept demonstrated a fully working host filesystem read/write from inside a standard, non-privileged container.
What made CVE-2019-5736 in runc so dangerous?
CVE-2019-5736 was dangerous because it let an attacker overwrite the host's own runc binary from inside a container, which meant every subsequent container start or docker exec on that host would execute attacker-controlled code as root. The attack abused the fact that runc re-executes itself via /proc/self/exe when starting a container; a malicious container image could race that self-exec and replace the target binary before the host process opened it, achieving a write to a file outside the container's mount namespace. It carried a CVSS score of 8.6 and affected Docker versions before 18.09.2, containerd before 1.2.6, and any Kubernetes cluster running those runtimes underneath. Because the exploit only required running a malicious image or getting shell access to an existing container — no privileged flag, no special mount, no misconfiguration — it demonstrated that "container escape" bugs don't require operator error. The runc maintainers shipped the fix in runc 1.0.0-rc7 within roughly ten days of coordinated disclosure, but the incident reshaped how the ecosystem thinks about default trust in base images.
Can a misconfigured container escape without any CVE at all?
Yes — a container running with the --privileged flag, mounting /var/run/docker.sock, or dropped into the host's PID or network namespace can be escaped using nothing but standard Linux tooling, with no vulnerability required. A privileged container has every kernel capability and no seccomp/AppArmor restrictions, so a process inside it can mount the host's block devices directly and chroot into the host filesystem in a handful of commands. Mounting the Docker socket into a container is functionally equivalent to handing that container root on the host, because it can simply ask the Docker daemon to start a new privileged container with a host bind mount. CVE-2022-0492 sits at the boundary between misconfiguration and vulnerability: disclosed by Yuval Avrahami of Unit 42 in February 2022 with a CVSS score of 7.8, it showed that a container with CAP_SYS_ADMIN could abuse the cgroup v1 release_agent file — present in the Linux kernel since version 2.6.24 — to trigger arbitrary code execution on the host, even without the --privileged flag, if that single capability was granted.
How can shared namespaces or host mounts lead to escape?
Shared namespaces and host mounts lead to escape because they deliberately remove the isolation boundary the container runtime would otherwise enforce, giving a compromised container a direct line to host resources. CVE-2020-15257, disclosed in December 2020 with a CVSS score of 7.7, showed this concretely: containerd's shim process exposed a control API over an abstract Unix domain socket, and abstract sockets are scoped to the network namespace rather than the filesystem. Any container configured with hostNetwork: true in Kubernetes shared the host's network namespace and could therefore reach that abstract socket and issue commands to the containerd-shim API as root — no exploit chain needed beyond the namespace-sharing configuration itself. The same logic applies to hostPID: true, which lets a container see and ptrace into host processes, and to mounting host paths like /etc, /var/run, or / into a container, which hands the container read/write access to files the isolation model was supposed to protect.
How do you detect container escape risk before attackers do?
You detect container escape risk by continuously scanning running images and base layers for known CVEs like CVE-2024-21626 or CVE-2022-0492, and by auditing runtime configuration for privileged mode, host namespace sharing, and host mounts before workloads reach production. Static image scanning alone catches the vulnerable-package case — an outdated runc or containerd version baked into a base image — but it misses configuration-driven escapes, which require inspecting Kubernetes admission policy, Pod Security Standards enforcement, and the actual securityContext fields on deployed workloads. The two failure modes compound: Palo Alto Networks' Unit 42 research on CVE-2022-0492 noted that the release_agent technique only becomes exploitable when a specific capability grant is present, meaning the vulnerability and the misconfiguration have to be assessed together, not as separate checklist items. Effective detection requires runtime-aware prioritization: knowing not just that a vulnerable runc binary exists somewhere in the cluster, but which nodes are actually running unpatched versions, which pods have the capabilities needed to exploit it, and which of those pods are internet-reachable.
How Safeguard Helps
Safeguard's reachability analysis correlates known container-escape CVEs — including runc, containerd, and cgroup-level flaws like CVE-2024-21626 and CVE-2022-0492 — against the actual runtime configuration of deployed workloads, so security teams see which pods carry both the vulnerable component and the capability grants or namespace settings needed to exploit it, instead of a flat list of every CVE in every image. Griffin AI triages that combined signal to rank which findings represent a real path to host compromise versus a patched-but-unused code path, cutting through alert volume that would otherwise bury a genuine escape risk. Safeguard generates and ingests SBOMs across the build pipeline to track exactly which runc or containerd version shipped in each image, closing the gap between "a CVE was published" and "we know which running containers are affected." Where a fix is available, Safeguard opens an auto-fix PR that bumps the vulnerable runtime or base image dependency, so the patch — like the runc 1.1.12 fix for Leaky Vessels — reaches production without a manual triage cycle.