Containers share the host kernel, so isolation is weaker than a VM - a container is a restricted host process, not a separate machine. Main risks: vulnerable base images/dependencies, secrets in image layers or env vars, root / privileged containers & excess capabilities, an exposed Docker daemon/socket (effectively root on the host), missing limits, and container escape (breaking out to the host - the worst case). Most incidents are configuration and privilege issues, not exotic exploits. Testing enumerates images for CVEs, hunts secrets, and checks privileges, capabilities, socket exposure and escape paths. Harden by minimising privilege everywhere: minimal trusted images, no baked-in secrets, non-root, drop capabilities, no privileged mode, no host socket/filesystem mounts, resource limits, and enforce it in CI/CD. Detail below; pairs with Kubernetes and cloud testing.
// 01 A container is not a VM
The most important thing to understand about container security is what a container is. A virtual machine has its own kernel and is strongly isolated by the hypervisor - a genuine boundary. A container is different: containers on the same host share the host's kernel, isolated only by operating-system features (namespaces and control groups). In other words, a container is a process on the host with restrictions, not a separate machine. That distinction has a sharp security consequence: the isolation is weaker, so a misconfigured or over-privileged container, or a kernel vulnerability, can allow container escape - breaking out to the host, and thereby compromising every other container on it. Treating a container like a VM - assuming strong isolation you don't actually have - is the mental error behind most serious container incidents. Container security is fundamentally about not weakening the isolation the platform gives you.
// 02 The container attack surface
Vulnerable images
Containers are built from base images that may carry known-vulnerable software and dependencies.
Secrets in images
Credentials baked into image layers or passed via plaintext environment variables.
Root & privilege
Running as root, privileged mode, or added capabilities that weaken the isolation.
Exposed daemon/socket
A reachable Docker daemon or mounted socket is effectively root on the host.
The theme is privilege and configuration, not zero-days. Most serious container incidents come from a container that was given too much power or built from a vulnerable image with a secret inside - all of which are choices you control.
// 03 Container escape - the worst case
Container escape is the outcome everything else is trying to prevent: an attacker who has compromised a container breaks out of its isolation to the underlying host, and from there potentially to every other container. Because containers share the host kernel, escape typically comes from excessive privilege - running the container in privileged mode, mounting the host filesystem or the Docker socket into the container (handing it control of the host), dangerous added capabilities - or from exploiting a kernel or runtime vulnerability. An escape is catastrophic because it turns the compromise of one application into compromise of the host and everything on it. It's the container equivalent of the privilege-escalation chains we hunt in cloud. This is exactly why hardening obsesses over minimising container privileges: the single most effective way to prevent escape is to ensure a compromised container simply doesn't have the power to break out.
// 04 How to test containers
Container testing works across the image, the runtime and the platform. Images: scan base images and dependencies for known-vulnerable software, and inspect layers for baked-in secrets. Runtime configuration: check whether containers run as root, in privileged mode, with excess capabilities, or with the host filesystem/Docker socket mounted - the escape enablers. Daemon/socket: test whether the Docker daemon or socket is exposed or reachable. Escape paths: from a foothold in a container, attempt to break out to the host using any weak privileges, proving real impact. And critically, test the CI/CD pipeline that builds and ships images, since that's where insecure images and secrets originate. It blends automated scanning with the manual escape testing that proves whether the isolation actually holds - and it sits alongside Kubernetes testing where an orchestrator is in play.
// 05 How to harden containers
The hardening playbook is a single idea applied everywhere: minimise privilege and attack surface. Images: use minimal, trusted, regularly-scanned base images and keep them patched; never store secrets in images or plaintext env vars - use a secrets manager. Runtime: run containers as a non-root user, drop unnecessary Linux capabilities, avoid privileged mode, and never mount the Docker socket or host filesystem into containers unless absolutely required. Platform: protect the Docker daemon and never expose it unauthenticated; apply resource limits and read-only filesystems where possible. Pipeline: enforce these controls in CI/CD so an insecure image can't ship. Then scan and pentest regularly to validate the configuration holds. Done consistently, this ensures that even a compromised application container is a contained problem - no escape, no host, no lateral blast. Engagements follow our methodology, alongside cloud testing where containers run in the cloud.
// 06 Frequently asked questions
How is container security different from a VM?
Isolation. A VM has its own kernel and is strongly isolated by the hypervisor; containers on the same host share the host's kernel and are isolated by OS features (namespaces, cgroups). That shared kernel makes isolation weaker - a container is a restricted host process, not a separate machine. So a misconfigured or over-privileged container, or a kernel vulnerability, can allow container escape to the host, compromising every other container. Security depends on not weakening the platform's isolation.
What are the main Docker security risks?
Vulnerable base images and dependencies; secrets baked into images or passed insecurely (credentials in layers or env vars); running as root or with excessive privileges (privileged mode, added capabilities); an exposed Docker daemon or socket (effectively root on the host); insecure config and missing resource limits; and container escape. Most serious incidents come from configuration and privilege issues, not exotic exploits.
What is container escape?
When an attacker who compromised a container breaks out of its isolation to the host, and potentially to other containers. Because containers share the host kernel, escape can result from excessive privilege - privileged mode, mounting the host filesystem or Docker socket, dangerous capabilities - or from a kernel/runtime vulnerability. It's the worst case because it turns one app's compromise into compromise of the host and everything on it, which is why hardening minimises privileges.
How do you secure Docker containers?
Minimise privilege and surface everywhere: minimal trusted, scanned, patched base images; no secrets in images or plaintext env vars (use a secrets manager); run non-root, drop capabilities, avoid privileged mode, don't mount the Docker socket or host filesystem unless essential; protect the daemon and never expose it unauthenticated; apply resource limits and read-only filesystems; enforce these in CI/CD so insecure images can't ship. Scan and pentest to validate it holds.
// 07 Related reading
- Kubernetes penetration testing — when an orchestrator sits above the containers.
- CI/CD pipeline security — where insecure images originate.
- Cloud penetration testing and our methodology.