Host namespace sharing as attack surface
--pid, --ipc, --net, --uts=host and what they expose.
Isolation is the default, but Docker lets a container opt out of individual namespaces by sharing the host’s — and every one you share is a hole punched straight through the boundary. These flags exist for legitimate reasons (monitoring agents, debugging, specialized networking), but each one hands the container a piece of the host, and in an untrusted workload each is an escape primitive. Knowing exactly what each shares is how you review them.
--pid=host and --net=host are the sharp ones
Sharing the PID namespace lets a container see every host process in /proc — including their command lines and, dangerously, their environment variables (where other people’s secrets often live) and open file descriptors. Add CAP_SYS_PTRACE and the container can attach to and inject code into host processes. Sharing the network namespace removes network isolation entirely: the container binds any host port, bypasses published-port mapping, and can sniff traffic on the host’s interfaces. Both are common in “it was easier” monitoring setups and both are serious exposure.
# with --pid=host a container reads other processes’ environments (secrets leak here)$ docker run --rm --pid=host alpine sh -c \'for e in /proc/[0-9]*/environ; do tr "\0" "\n" < "$e" 2>/dev/null; done | grep -i token'API_TOKEN=... DB_PASSWORD=... # secrets from unrelated HOST processes
When they are legitimately needed, scope them
Some tools genuinely need host visibility — a metrics agent may need --pid=host to see host processes, a network probe may need --net=host. The rule is the same as capabilities: grant the single namespace the tool proves it needs, never a blanket set, keep those containers trusted and minimal, and never combine host-namespace sharing with --privileged or a mounted socket. For everything else, the answer is no — the default isolated namespaces are correct.
# audit which running containers share host namespaces (each is a review item)$ for c in $(docker ps -q); dodocker inspect -f '{{.Name}} pid={{.HostConfig.PidMode}} net={{.HostConfig.NetworkMode}} ipc={{.HostConfig.IpcMode}}' "$c"done/metrics-agent pid=host net=default ipc= # expected for an agent — scoped/web pid= net=appnet ipc= # good: fully isolated