HIGH sandbox escapedocker

Sandbox Escape on Docker

How Sandbox Escape Manifests in Docker

Docker containers rely on Linux namespaces and cgroups to isolate processes from the host. A sandbox escape occurs when an attacker breaks out of these isolation mechanisms and gains execution privileges on the host or in other containers. In Docker‑specific contexts, the most common vectors are:

  • Privileged mode – running a container with --privileged gives it access to all host devices and effectively disables many namespace restrictions.
  • Exposed Docker socket – mounting /var/run/docker.sock inside a container allows the containerized process to issue Docker daemon commands, such as docker run with privileged flags, leading to a host escape.
  • Dangerous Linux capabilities – granting capabilities like SYS_ADMIN, SYS_PTRACE, or CAP_SYS_MODULE lets a container perform operations that can modify host kernel state or break out of namespaces.
  • Insecure volume mounts – bind‑mounting host directories such as /, /etc, or /dev can give a container read/write access to critical host files.
  • Known runtime exploits – vulnerabilities like CVE‑2019‑5736 (runc) allow overwriting the host runc binary via a malicious container image, leading to host code execution.

For example, a Dockerfile that builds an image intended to run as root and then executes a container with --privileged -v /var/run/docker.sock:/var/run/docker.sock creates a direct path to escape:

# Dockerfile (bad practice)
FROM alpine:latest
USER root
CMD ["/bin/sh"]

# docker run command (bad practice)
docker run --rm -it \
  --privileged \
  -v /var/run/docker.sock:/var/run/docker.sock \
  myimage

When the container starts, any process inside can talk to the Docker daemon via the socket and launch another container with privileged flags, effectively executing arbitrary code on the host.

Docker-Specific Detection

Detecting a potential sandbox escape involves examining the container’s runtime configuration for the risky patterns described above. Since middleBrick performs unauthenticated black‑box scans, it can identify exposed Docker APIs and infer risky container settings from the responses.

What middleBrick looks for:

  • Responses from endpoints that expose the Docker Engine API (typically on tcp://0.0.0.0:2375 or unix:///var/run/docker.sock) without authentication.
  • HTTP headers or body indicators that suggest a container is running in privileged mode (e.g., X-Docker-Privileged: true in custom middleware, or diagnostic endpoints that leak HostConfig.Privileged).
  • Volume mount information leaked through debug endpoints that show bindings like /var/run/docker.sock or host root directories.
  • Presence of dangerous capabilities in container metadata (if the API returns HostConfig.CapAdd containing SYS_ADMIN, SYS_PTRACE, etc.).

Example of a scan via the middleBrick CLI:

# Install the CLI (npm)
npm i -g middlebrick

# Scan an API that may expose Docker socket
middlebrick scan https://api.example.com/docker

The output includes a risk score (A–F) and a finding such as:

Finding IDCategorySeverityDescription
DOCK-001Privilege EscalationHighDocker socket exposed without authentication; container likely runs with privileged flag.
DOCK-002Container MisconfigurationMediumVolume mount includes host root directory (/).

These findings give developers actionable guidance: secure the Docker daemon, remove privileged flags, and restrict volume mounts.

Docker-Specific Remediation

Remediation focuses on eliminating the risky configurations that enable escape. Use Docker’s native features to enforce least privilege.

1. Avoid privileged mode
Run containers without --privileged. If specific capabilities are needed, drop all others and add only the required ones.

# Good: drop all capabilities, then add only NET_BIND_SERVICE if needed
docker run --rm \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  myimage

2. Secure the Docker socket
Never mount /var/run/docker.sock into a container unless absolutely necessary, and if you do, protect it with authentication (e.g., using a TLS‑protected socket or a proxy that enforces auth).

# Example of using a TCP socket with TLS (requires daemon configuration)
docker run --rm \
  -e DOCKER_HOST=tcp://docker.example.com:2376 \
  -e DOCKER_TLS_VERIFY=1 \
  -e DOCKER_CERT_PATH=/certs \
  myimage

3. Use user namespaces and non‑root users
Enable userns-remap on the daemon to map container root to an unprivileged host UID, and run processes as a non‑root user inside the container.

# Docker daemon config (/etc/docker/daemon.json)
{
  "userns-remap": "default"
}

# Dockerfile
FROM alpine:latest
RUN addgroup -S app && adduser -S -G app app
USER app
CMD ["/app/start.sh"]

4. Limit dangerous capabilities
Explicitly drop capabilities that are not needed, especially SYS_ADMIN, SYS_PTRACE, and CAP_SYS_MODULE.

docker run --rm \
  --cap-drop SYS_ADMIN,SYS_PTRACE,CAP_SYS_MODULE \
  myimage

5. Restrict volume mounts
Bind‑mount only the specific directories the container needs, and mount them read‑only when possible.

docker run --rm \
  -v /app/data:/data:ro \
  -v /etc/myapp:/etc/myapp:ro \
  myimage

After applying these changes, re‑run a middleBrick scan to verify that the risk score improves and the Docker‑specific findings disappear.

Frequently Asked Questions

Does middleBrick modify my Docker containers to prevent sandbox escapes?
No. middleBrick only detects and reports risky configurations such as exposed Docker sockets, privileged flags, or dangerous volume mounts. It provides remediation guidance, but you must apply the fixes yourself in your Dockerfiles or deployment scripts.
Can I use middleBrick to scan internal APIs that are not publicly reachable?
Yes. As long as the API endpoint is reachable from the machine where you run the middleBrick CLI or GitHub Action, you can scan it. The tool works with any URL you provide, including internal or localhost addresses, without requiring agents or credentials.