Containers are not VMs. They share a kernel. They share namespaces. They share cgroups. The isolation boundary is a software construct maintained by the kernel — not a hardware boundary maintained by a hypervisor. Understanding what containers actually isolate is the difference between security and theater.
A container escape is not a theoretical attack. It happens regularly. The kernel is a massive attack surface. Every syscall is a potential vector. Every capability is a potential privilege escalation path. The container runtime is a thin wrapper around kernel features — and kernel features have bugs.
THE DEEP DIVE
Namespace Isolation
Linux namespaces isolate different aspects of the system: PID (processes), NET (network), MNT (filesystem), UTS (hostname), IPC (inter-process communication), USER (user IDs), and CGROUP (cgroup root). A container gets its own set of namespaces. The host sees all of them.
# The container sees:
PID 1 = nginx
NET = its own network stack
MNT = its own filesystem view
# The host sees:
PID 12345 = nginx (running in a namespace)
NET = veth pair connected to bridge
MNT = overlayfs mount
# The shared resource:
KERNEL = the same kernel for both
Common Escape Vectors
The most common escape vectors exploit the shared kernel: CVE-2022-0185 (heap overflow in filesystem context), CVE-2022-0492 (cgroup escape), CVE-2021-3493 (overlayfs privilege escalation). Each of these exploits the gap between what the container thinks it has and what the kernel actually provides.
PRINCIPLES
- Containers share a kernel. The kernel is the attack surface. Minimize kernel exposure.
- Root inside a container is root on the host if capabilities are not restricted.
- Seccomp profiles are not optional. They are the last line of defense between container and kernel.
- Read-only rootfs is not a performance optimization. It is a security boundary.
- The container runtime should be the most boring, most audited, most patched software in your stack.
IN PRACTICE
Capability Restriction
Drop all capabilities except NET_BIND_SERVICE. The container can bind to port 80 and nothing else. No mount, no chown, no kill, no reboot. The attack surface is reduced to the syscalls allowed by the seccomp profile.
Seccomp Profile
A custom seccomp profile that allows only 40 of the 300+ Linux syscalls. The container cannot mount filesystems, load kernel modules, or access hardware. The profile is generated from a trace of normal application behavior.
LIVE SIGNALS
These items surfaced from the intelligence pipeline at generation time.
- CVE-1999-0095 — The debug command in Sendmail is enabled, allowing attackers to execute commands as root. (NVD / CVE)
- CVE-1999-1471 — Buffer overflow in passwd in BSD based operating systems 4.3 and earlier allows local users to gain root privileges by specifying a long shell or GECOS field. (NVD / CVE)
- CVE-1999-1122 — Vulnerability in restore in SunOS 4.0.3 and earlier allows local users to gain privileges. (NVD / CVE)
- CVE-1999-1506 — Vulnerability in SMI Sendmail 4.0 and earlier, on SunOS up to 4.0.3, allows remote attackers to access user bin. (NVD / CVE)
- CVE-1999-0084 — Certain NFS servers allow users to use mknod to gain privileges by creating a writable kmem device and setting the UID to 0. (NVD / CVE)
ANTIPATTERNS
- Running containers as root without justification.
- Using the default Docker seccomp profile without customization.
- Mounting the Docker socket inside a container. This is equivalent to giving the container root on the host.
- Ignoring container image scanning. A vulnerable base image is a vulnerable container.
CHECKLIST
- Containers run as non-root users
- All capabilities are dropped except those explicitly needed
- Seccomp profile is applied and tested
- Root filesystem is read-only
- Docker socket is not mounted
- Container images are scanned for vulnerabilities
YOUR MOVE
Run docker inspect on your containers. Check the CapAdd and SecurityOpt fields. If CapAdd is not empty or SecurityOpt does not include seccomp, you have work to do.