Infra Audit5 min readUpdated November 4, 2026

The Docker Socket Is a Root Backdoor

CI runners, Portainer, Watchtower and monitoring agents all mount it. One compromised container later, the host is gone. The mechanism is by design, not by bug.

The Docker socket is the daemon's API, and the daemon runs as root. A container with the socket can create a privileged container that mounts the host root. Check every container's Binds for docker.sock.

The socket at /var/run/docker.sock accepts the same REST API as the daemon. A container with it mounted runs curl --unix-socket /var/run/docker.sock and speaks to the daemon as root. It creates a new container with Privileged: true and a bind mount of /, then execs into it. The host filesystem is now a local directory.

The mechanism, step by step

The socket at /var/run/docker.sock accepts the same REST API as the daemon. A container with it mounted runs curl --unix-socket /var/run/docker.sock and speaks to the daemon as root. It creates a new container with Privileged: true and a bind mount of /, then execs into it. The host filesystem is now a local directory.
The socket at /var/run/docker.sock accepts the same REST API as the daemon. A container with it mounted runs curl --unix-socket /var/run/docker.sock and speaks to the daemon as root. It creates a new container with Privileged: true and a bind mount of /, then execs into it. The host filesystem is now a local directory. No kernel exploit, no CVE, no crash. The design trusts whoever holds the socket, and the mount hands it over.

Why it is everywhere

Tools that manage other containers need the socket: Portainer, Watchtower, Traefik's docker provider, CI runners, monitoring agents. Each install is a standing root-equivalent on the host.
Tools that manage other containers need the socket: Portainer, Watchtower, Traefik's docker provider, CI runners, monitoring agents. Each install is a standing root-equivalent on the host. The compromise path is usually the containerized app itself: a vulnerable web app in a container that also has the socket is a full host compromise waiting for one SSRF or RCE.

The privileged variant

Privileged: true removes capability filtering entirely. With cgroup v1, the classic escape writes a script path into release_agent inside a writable cgroup and triggers release: the host kernel executes the script as root. No socket needed.
Privileged: true removes capability filtering entirely. With cgroup v1, the classic escape writes a script path into release_agent inside a writable cgroup and triggers release: the host kernel executes the script as root. No socket needed. The audit checks both shapes on every container, plus the network variant: Docker API listening on TCP 2375 without TLS, which is the same power for anyone who can reach the port.

If it stays

Every container on that host is one web vulnerability away from the whole machine, and the machine is one credential away from the rest of the environment. The fix is scoping: rootless Docker, a socket proxy that filters API calls, or moving the managing tool to a dedicated VM.
Every container on that host is one web vulnerability away from the whole machine, and the machine is one credential away from the rest of the environment. The fix is scoping: rootless Docker, a socket proxy that filters API calls, or moving the managing tool to a dedicated VM. The audit re-runs the same inspect command after the change and expects zero socket mounts.

4 Tips to Get Started

1

docker inspect $(docker ps -q) --format '{{.Name}} {{.HostConfig.Binds}}' lists every mount. Any docker.sock entry is P0.

2

Privileged: true is the same risk without the socket: cgroup release_agent escape runs code on the host as root.

3

Docker API on TCP 2375 without TLS is the same power over the network, unauthenticated.

4

If a tool needs the socket, scope it: rootless Docker, a socket proxy with filtered endpoints, or a dedicated VM.

Ready to Stop Worrying About Infra?

Knowledge is the first step. Get a free 1-hour diagnostic and see where your infrastructure leaks time, money, and focus.

R

Ron Cohen — DevOps engineer & founder, roqy.io

Content reviewed by the roqy.io team. Our guides are based on publicly available data.

Disclaimer: This content is for informational and educational purposes only. It does not constitute professional advice or a guarantee of specific results. Infrastructure needs vary by team, stack, and stage. Consult a qualified engineer for advice tailored to your situation.

Frequently Asked Questions

Can a Docker container escape to the host?

Yes, without any kernel exploit, if it has the Docker socket mounted or runs privileged. The socket is the daemon's API; a container with it can create a new privileged container that mounts the host root. Privileged containers can escape via cgroup release_agent. Both are common in CI runners and monitoring agents.

Why is mounting docker.sock dangerous?

The socket is the Docker daemon API over a unix socket, and the daemon runs as root on the host. A container with the socket can call the API to create a privileged container with the host filesystem mounted, then read or modify anything. The isolation boundary is bypassed by design.

How do I check for it?

docker inspect $(docker ps -q) --format '{{.Name}} {{.HostConfig.Binds}}'. Any Binds entry containing docker.sock is a critical finding. Also check HostConfig.Privileged and the published ports for 2375.

Get the DevOps Ecosystem Behind You

One accountable engineer. Full platform behind him. Month-to-month, no lock-in.