In my company, I was recently given access to the docker group to run containers. This sounded standard, but it led me to discover how I could gain functional root privileges on the host machine just by being a member of this group.
To understand how, let’s agree on a common Docker principle: The Docker Daemon runs as a root process.
The Docker CLI interacts with the daemon through a Unix socket (/var/run/docker.sock). If you have access to the CLI (which the docker group gives you), you have read and write access to this socket.
The Exploit: Breaking the Isolation
In general, Docker images run as isolated processes. But something "magical" happens when we run a container by mounting the host’s root file system.
Consider this command:
docker run -v /:/host_root -it centos bash
Here, the container now has read/write access to the host system's root directory (/). By mounting it as a volume, we bypass the container's Union Filesystem (and lose the Copy-On-Write isolation) for that specific path.
The chroot trick
At this stage, we have just mounted the file system. If I try to install a service (e.g., yum install tree) inside the container normally, it installs in the container's /usr/bin, not the host's.
But, suppose I run this command inside the container:
chroot /host_root
The chroot (Change Root) command changes the apparent root directory for the current running process.
- I am telling my process: "Treat the mounted /host_root as your actual / directory."
- The root user in a container usually has a UID of 0.
- The Linux Kernel allows UID 0 to do whatever it wants.
At this point, even though I’m still inside a container, I’m operating directly on the host’s filesystem with root-level permissions — which is just as dangerous in practice.
If I install a package now, it installs on the host. If I delete a file, it is deleted from the host.
How to manage this?
Since granting docker group access is essentially granting root access, here is how we can secure it:
- Rootless Docker: Run the Docker daemon as a non-root service. However, rootless Docker comes with trade-offs: reduced performance and limitations around direct access to storage and the networking stack. So it has to add some wayaround, that incurs additional overhead.
- Read-Only Mounts: If you must mount the host filesystem, enforce read-only access: docker run -v /:/host_root:ro ...
- Principle of Least Privilege: Try adding minimal users to the docker user.
- Secure Dockerfiles: When creating images, explicitly create a non-root user. Example of a secure user setup:
RUN groupadd -r container_user && useradd -r -g container_user container_user
RUN chown -R container_user:container_user /host_root
USER container_user
Top comments (1)
This is a strong and accurate explanation of a misconception many teams still have about Docker security.👍