Docker Volume Misconfiguration: Sensitive Host Path Exposure and Container-to-Host Escalation
Theory
Why This Matters
Volume misconfiguration is among the most consistent findings in container security assessments. In 2021, the Azurescape vulnerability in Azure Container Instances was partially enabled by host filesystem access through a container volume mount. In enterprise environments, security researchers routinely find development practices carried into production: containers mounting /etc, /var/log, /root, or /proc for "convenience" or debugging, creating straightforward paths to host credential access, log injection, and privilege escalation. Unlike the Docker socket, sensitive volume mounts are easy to overlook because they appear to be mere file sharing — until an attacker in the container modifies /etc/passwd or reads the host's SSH private keys.
Core Concept
Docker volumes and bind mounts allow containers to access host filesystem paths. A bind mount maps a specific host path directly into the container namespace — changes made inside the container affect the host. A named volume uses Docker's volume management, typically stored under /var/lib/docker/volumes/, and is safer because it does not expose arbitrary host paths.
High-risk host path mounts:
- /etc — contains passwd, shadow, sudoers, cron.d, ssh/sshd_config, and host certificates. Write access to /etc/passwd allows adding new root users.
- /root — contains .ssh/authorized_keys, .aws/credentials, .bashrc, and shell history.
- /proc — the process filesystem. Writing to /proc/sysrq-trigger can trigger immediate host reboot or panic. Reading /proc/[PID]/environ exposes environment variables of host processes including other containers.
- /sys — access to kernel parameters and hardware. Writing to cgroup hierarchies in /sys/fs/cgroup can affect resource limits of host processes.
- /var/run — contains Unix sockets for host services. Mounting this path can expose the Docker socket and other privileged IPC mechanisms.
- /tmp on the host — world-writable shared space; useful for symlink attacks and tmpfs-based privilege escalation.
World-writable named volumes are also a finding: if a named volume is mounted into multiple containers and one container has write access, it can plant malicious files (cron jobs, shared library overwrites) that affect other containers mounting the same volume.
Detection requires inspecting HostConfig.Binds and HostConfig.Mounts for each container using docker inspect. Automated tools like trivy, kube-bench, and the CIS Docker Benchmark scanner check for sensitive path mounts.
Technical Deep-Dive
# Inspect all volume mounts for all running containers
docker ps -q | while read cid; do
name=$(docker inspect "$cid" --format '{{.Name}}')
binds=$(docker inspect "$cid" --format '{{json .HostConfig.Binds}}')
mounts=$(docker inspect "$cid" --format '{{json .Mounts}}')
echo "=== Container: $name ==="
echo "Binds: $binds"
echo "Mounts: $mounts"
done
# Filter for high-risk host path mounts
docker ps -q | xargs -I{} docker inspect {}
--format '{{.Name}}: {{.HostConfig.Binds}}' |
grep -Ei '/etc|/root|/proc|/sys|/var/run|/boot|/dev' |
grep -v '^[[:space:]]*[]'
# Detailed mount inspection for a specific container
docker inspect target-container
--format '{{json .HostConfig.Mounts}}' | python3 -m json.tool
# From inside a container: check what host paths are mounted
cat /proc/mounts | grep -v 'cgroup|proc|sysfs|devpts|shm|mqueue|overlay'
# If /etc is mounted read-write — demonstrate host user addition (authorised test)
# ls /etc/passwd — confirm it is the host file (not container's)
# stat /etc/passwd | grep Inode — compare with a known host inode
# Check for world-writable volume directories on the host
docker volume ls --format '{{.Name}}' | while read vol; do
mp=$(docker volume inspect "$vol" --format '{{.Mountpoint}}')
if [ -d "$mp" ]; then
perm=$(stat -c '%a' "$mp")
echo "Volume: $vol Mountpoint: $mp Permissions: $perm"
fi
done
# Run trivy for misconfiguration detection (includes volume checks)
trivy config ./docker-compose.yml
trivy image --security-checks config target-image:latest
# VULNERABLE docker-compose.yml
services:
app:
image: myapp:latest
volumes:
- /etc:/host-etc:rw # CRITICAL: host /etc writable from container
- /root:/host-root:ro # HIGH: host root home readable — SSH keys, credentials
- /proc:/host-proc:ro # HIGH: process environment variable disclosure
- app-data:/app/data # OK: named volume, isolated
# SECURE: use named volumes or specific non-sensitive paths
services:
app:
image: myapp:latest
volumes:
- app-data:/app/data # named volume — no host path exposure
- ./config:/app/config:ro # specific config directory, read-only
volumes:
app-data:
driver: local
Security Assessment Methodology
- Enumerate all container volume mounts. Run
docker inspecton all containers and collectHostConfig.BindsandMountsarrays. Build a complete list of host paths exposed to containers. - Classify by sensitivity. Categorise each host path mount: critical (
/etc,/root,/proc/sysrq-trigger), high (/var,/proc,/sys), medium (application data paths outside the container's scope), low (expected application config or log paths). - Test write access from inside containers. For each sensitive mount, verify whether it is mounted read-write or read-only. Read-only sensitive mounts are still findings (credential disclosure) but lower severity than read-write mounts (privilege escalation, persistence).
- Check for cross-container volume sharing. Identify named volumes mounted into multiple containers. If a lower-trust container has write access to a volume also mounted by a higher-trust container, the lower-trust container can plant malicious shared libraries or configuration files.
- Check docker-compose files in the repository. Grep for
volumes:sections and flag any host path mounts. Use Checkov (checkov -d . --check CKV_DOCKER_*) to automate this scan across all compose files. - Remediate by replacing all host path bind mounts with named volumes or no mounts, mounting only the specific paths needed and only as read-only where write is not required, and using Docker's
--read-onlycontainer filesystem flag combined with specific tmpfs mounts for writable paths.
Common Assessment Errors
- Treating read-only mounts as non-findings.
/rootmounted read-only still exposes SSH private keys, AWS credentials, and shell history./procmounted read-only still exposes environment variables of all host processes via/proc/[PID]/environ. Read-only does not mean safe. - Missing tmpfs mounts with sensitive data.
docker run --tmpfs /run:rw,noexec,nosuid,size=65536kcreates in-memory volumes. While they do not persist host data, they can still be shared between containers and may contain sensitive runtime data. - Not checking docker-compose override files. Many projects have
docker-compose.ymlanddocker-compose.override.yml. The override file often adds development-convenience mounts (including source code with.envfiles and credential directories) that are accidentally deployed to production. - Ignoring volume driver plugins. Third-party Docker volume plugins (NFS, AWS EFS, Azure Files) may mount remote filesystems that span multiple hosts. A container with write access to such a volume can affect other hosts mounting the same network share.
- Overlooking
/devmounts. Mounting host/devinto a container provides access to raw disk devices — with sufficient capability, this enables reading host disk contents without going through the filesystem. Check for/devmounts alongside other sensitive paths.
NICE Framework Alignment
| Code | Knowledge/Skill/Task Statement | How This Card Develops It |
|---|---|---|
| K0053 | Knowledge of security risk management processes | Assessing volume mount risk: sensitive host path exposure in containers is an insider threat and container escape vector that bypasses network controls |
| K0167 | Knowledge of system administration, network, and OS hardening techniques | Hardening Docker volume configurations: named volumes over bind mounts, read-only mount flags, and --read-only container filesystem enforcement |
| S0073 | Skill in conducting vulnerability scans and recognizing vulnerabilities | Using docker inspect and Checkov to enumerate and classify container volume mounts by sensitivity, identifying host path exposure |
| T0144 | Conduct penetration testing as required for new or updated applications | Testing sensitive volume mount access from inside containers during container security assessments to demonstrate host credential and filesystem exposure |
| T0395 | Write code to address security vulnerabilities | Refactoring docker-compose.yml volume configurations to use named volumes, read-only bind mounts, and minimal host path exposure |
Further Reading
- CIS Docker Benchmark, Section 5: Container Runtime — Center for Internet Security (cisecurity.org)
- Docker Security — Best Practices for Container Deployments — Sysdig Blog, Volume Security section (sysdig.com/blog)
- Container Security — Liz Rice, Chapter 7: Container Filesystem Isolation (O'Reilly Media)
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.