Capability & kernel escapes
SYS_ADMIN, /proc, and CVE-driven breakouts.
Beyond the big three, the deeper escapes abuse the fact that all containers share one kernel: an over-granted capability or a kernel vulnerability can cross the boundary directly. These are rarer and more technical, but understanding the classes tells you which capabilities to guard and why keeping the host patched is a container-security control, not just general hygiene.
Capability-driven escapes
A handful of capabilities are escape primitives on their own. CAP_SYS_ADMIN allows mount operations that have been chained into breakouts (the classic release_agent/cgroup technique needed SYS_ADMIN plus a writable cgroup mount). CAP_SYS_MODULE lets a container load a kernel module — instant, total host control. CAP_SYS_PTRACE with a shared PID namespace lets a container inspect and hijack host processes. CAP_DAC_READ_SEARCH has been used to read arbitrary host files. The through-line: these are exactly the capabilities cap-drop ALL removes, which is why the drop matters so much.
# the defense is verification: confirm production containers hold none of these$ docker run --rm --cap-drop ALL alpine sh -c \'apk add -q libcap; capsh --print | grep -E "sys_admin|sys_module|sys_ptrace|dac_read"' \|| echo "none of the escape-grade caps present — good"none of the escape-grade caps present — good
Kernel-vulnerability escapes
Because the kernel is shared, a kernel privilege-escalation bug reachable from a container syscall can be an escape — Dirty COW, Dirty Pipe, and various netfilter and io_uring flaws have all been demonstrated as container breakouts. There is no in-container configuration that fully fixes a kernel bug; the defenses are to reduce the syscalls that reach the kernel (seccomp), patch the host promptly, and for genuinely untrusted workloads put a stronger boundary around the kernel entirely — which is the next lesson.