# CL-0013: Sensitive Host Path Mounted

**Severity:** HIGH (CRITICAL when the entire host root filesystem is mounted)

**References:**
- [OWASP Docker Security Rule #8](https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-8-set-filesystem-and-volumes-to-read-only)
- CIS Docker Benchmark 5.6 — Ensure sensitive host system directories are not mounted on containers

## What it detects

Services that bind-mount sensitive host directories into a container:
- `/` — the entire host root filesystem (CRITICAL — one-line container escape)
- `/etc` — host system configuration
- `/proc` — kernel and process information
- `/sys` — kernel device and driver interfaces
- `/boot` — bootloader and kernel images
- `/dev` — entire host device tree (per-device exposure is CL-0016)
- `/root` — root user's home directory (SSH keys, shell history)
- `/var/lib/docker` — Docker daemon state, including images and other containers
- `/var/lib/kubelet` — Kubernetes node state, pod secrets, and service account tokens
- `/var/run` — runtime sockets (parent of `/var/run/docker.sock`)
- `/run/containerd` — containerd runtime sockets and state
- `/run/systemd` — systemd D-Bus sockets; can be used to drive arbitrary unit start/stop on the host
- `/home` — user home directories with credentials and source code

Subpaths (e.g., `/etc/passwd`, `/root/.ssh`) are also flagged. Both short syntax (`/etc:/host-etc`) and long syntax (`source: /etc, target: /host-etc`) are checked. The long syntax is recognized whether `type: bind` is set explicitly or omitted — Compose treats absolute-path sources as bind mounts either way. Named volumes are not flagged.

Read-only mounts (`:ro`) are not differentiated from read-write today. A read-only mount of `/etc` is materially less dangerous than a read-write mount of the same path — readable secrets only, no host modification — but still leaks shadow files, SSH host keys, and configuration. Suppress with `reason:` if your use case genuinely only reads non-sensitive subdirectories, or scope the mount narrower.

## Why it matters

Mounting these paths gives the container read (and potentially write) access to critical host infrastructure:
- `/` is a complete container escape — the workload has full access to the host filesystem
- `/etc` contains `shadow`, `sudoers`, `ssh` configs — a writable mount enables full host takeover
- `/proc` exposes kernel parameters, process environments (secrets), and sysrq triggers
- `/sys` provides direct interfaces to hardware, cgroups, and kernel modules
- `/boot` contains the kernel and initramfs — modification enables persistent rootkits
- `/dev` mounts the entire device tree, equivalent to many of CL-0016's individual flags
- `/root` and `/home` typically contain SSH keys, cloud credentials, and shell history
- `/var/lib/docker` exposes other containers' filesystems and image layers
- `/var/lib/kubelet` exposes pod-level secrets and service account tokens on Kubernetes nodes
- `/var/run` is the parent of the Docker socket and other privileged sockets
- `/run/containerd` and `/run/systemd` expose runtime control sockets that drive privileged actions on the host

## Fix

Remove the bind mount. If the container needs specific host files, copy them into the image at build time or use a named volume containing only the required data:

```yaml
# Before
services:
  app:
    image: myapp:1.0
    volumes:
      - /etc:/host-etc

# After — use a named volume or COPY in Dockerfile
services:
  app:
    image: myapp:1.0
    volumes:
      - app-config:/app/config
```

## See also

- [CL-0001](CL-0001.md) — `/var/run/docker.sock` (the canonical privileged socket under `/var/run`)
- [CL-0016](CL-0016.md) — individual dangerous host devices (per-device, where this rule covers whole `/dev`)
