In January 2024, researchers disclosed CVE-2024-21626, a runc container escape with a CVSS score of 8.6 that let an attacker break out of a container and gain root access on the underlying host through a leaked file descriptor. It was patched in runc 1.1.12, but by then runc — the low-level runtime under Docker, containerd, and Kubernetes — had already shipped the flaw in every release since 1.0.0-rc93. That single bug illustrates the core problem with Docker security: vulnerabilities compound across layers you don't fully control — the daemon, the runtime, the base image, and the application you actually wrote. Security teams scanning containers for CVEs often stop at "known vulnerable package," missing daemon misconfigurations, privilege escalation paths, and secrets baked into image history. Below are the five Docker security vulnerabilities that show up most often in real incidents, with the mechanics of each and how to close them.
What is CVE-2024-21626 and how does it let attackers escape a container?
CVE-2024-21626 lets a malicious or compromised container process gain access to the host filesystem by exploiting a leaked internal file descriptor (/proc/self/fd) during the WORKDIR handling in runc, effectively giving the container process a working directory rooted on the host instead of inside its own namespace. Any command executed after that — including instructions from a malicious Dockerfile or an image pulled from an untrusted registry — could then read and write host files. It affected runc versions up to 1.1.11, and by extension Docker Engine before 25.0.2 and containerd before 1.6.28. What made it dangerous wasn't just the escape itself but the attack surface: build processes that execute untrusted Dockerfiles in CI, and multi-tenant platforms that run customer-supplied images, were both directly exploitable without any special privileges. Patching runc and the container runtime is necessary but not sufficient — teams also need to know which running images and build pipelines were exposed during the window between disclosure and patch, which for most organizations was measured in weeks, not hours.
Why is an exposed Docker daemon socket the fastest path to host takeover?
An exposed Docker daemon socket is the fastest path to host takeover because the Docker API has no built-in authentication by default, so anyone who can reach it can launch a privileged container and mount the host filesystem inside it. This isn't theoretical: Kinsing malware has been scanning the internet for misconfigured Docker APIs on TCP port 2375 since at least 2019, and Trend Micro and Aqua Security have both documented ongoing Kinsing campaigns as recently as 2024 that compromise exposed daemons within minutes of discovery to deploy cryptomining payloads. The attack is simple — docker -H tcp://target:2375 run -v /:/host -it alpine chroot /host sh hands the attacker a root shell on the host — which is exactly why it remains one of the most automated, high-volume attack patterns against cloud infrastructure. The fix is straightforward but frequently skipped under deadline pressure: never bind the Docker socket to 0.0.0.0, require TLS client certificate authentication for any remote API access, and treat /var/run/docker.sock mounted into a container as equivalent to handing that container root on the host.
How many container images actually ship with known critical CVEs like Log4Shell?
A large share of production container images still ship with known critical CVEs, and Log4Shell (CVE-2021-44228) is the clearest example of how long these vulnerabilities persist. Log4Shell was disclosed in December 2021 with a CVSS score of 10.0, yet vendor scanning reports have continued to find vulnerable Log4j versions embedded in production container images years later, largely because the library gets pulled in transitively through Java frameworks and rarely gets revisited once a service is running. Sysdig's 2023 Cloud-Native Security and Usage Report found that 60% of the container images they analyzed contained at least one critical or high-severity vulnerability that already had a fix available at the time of deployment — meaning the vulnerable code was shipped despite a patched version already existing upstream. The pattern repeats with every base-image CVE: a fix ships, but images built weeks or months earlier keep getting deployed from cached registries and CI artifact stores. Continuous image scanning at build time catches new CVEs; the harder problem is re-scanning everything already running in production as new CVEs are disclosed against packages that were "clean" the day the image was built.
What makes privileged containers and excessive Linux capabilities so dangerous?
Privileged containers are dangerous because the --privileged flag disables nearly every isolation mechanism Docker relies on — including seccomp filtering, AppArmor/SELinux confinement, and most Linux namespace restrictions — giving the container direct access to all host devices and kernel capabilities. TeamTNT's cryptomining campaigns, tracked by multiple threat intelligence teams since 2020, specifically targeted misconfigured Docker deployments with exposed APIs or privileged containers to pivot from a single compromised container to full host and cluster compromise. Even short of full --privileged mode, individual capabilities like CAP_SYS_ADMIN or CAP_SYS_PTRACE can be combined with kernel bugs — such as CVE-2022-0847 ("Dirty Pipe"), a Linux kernel privilege escalation disclosed in March 2022 — to escape a container that was never marked privileged at all. The rule that actually holds up in practice: run containers with --cap-drop=ALL and add back only the specific capabilities the workload needs, and treat any request for --privileged in a pull request as a finding that requires its own security review, not a default convenience flag.
How do secrets end up baked into Docker image layers — and why can't you just delete them?
Secrets end up baked into Docker image layers because every RUN, COPY, and ENV instruction creates a new, immutable layer, and deleting a file or unsetting a variable in a later layer doesn't remove it from the earlier layer where it was written — it's still sitting in the image history, extractable with a simple docker history or docker save and unpack. GitGuardian's 2023 State of Secrets Sprawl report found that public Docker Hub repositories were a consistent source of leaked credentials, with hardcoded API keys, database connection strings, and cloud provider tokens recovered from images whose Dockerfiles had "cleaned up" the secret in a subsequent RUN rm instruction that never actually removed it from the image. Multi-stage builds solve this correctly by discarding the build stage — and its layers — entirely, keeping secrets out of the final image rather than trying to delete them after the fact. Docker's --secret mount flag (available since BuildKit) and short-lived, injected-at-runtime credentials solve the same problem without ever writing the secret to disk inside the build context in the first place.
How Safeguard Helps
Safeguard closes the gap between "a CVE exists in this image" and "this CVE is actually exploitable in your environment" through reachability analysis, tracing whether the vulnerable function in a package like Log4j or runc is actually invoked by your code paths before it gets prioritized for remediation. Griffin AI correlates that reachability data against your running container inventory and generates auto-fix pull requests that bump the vulnerable base image or dependency to a patched version without breaking your build. Safeguard also generates and ingests SBOMs across your image registries, so when the next runc-style or Log4Shell-style CVE drops, you can immediately identify every affected image and build pipeline instead of re-scanning your entire fleet from scratch. For daemon exposure and privileged-container misconfigurations specifically, Safeguard's posture checks flag exposed sockets, --privileged usage, and excessive capability grants directly in CI before they reach production.