Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy Docker Security
Intermediate · 20 min

Docker Security

Learn how running containers as root, privileged mode, and secrets in ENV create container escape risks.

1 Container Security Misconfigurations

Docker provides isolation but is not a security boundary by itself. Common misconfigurations can lead to container escape and host compromise.

Running as root:

# Vulnerable: default root user
FROM ubuntu:20.04
RUN apt-get install -y myapp
CMD ["myapp"]  # Runs as root inside container!

If an attacker gains code execution in a root container, privilege escalation to the host is much easier via kernel exploits or volume mounts.

Privileged containers:

docker run --privileged myapp
# Gives container nearly all host capabilities
# Can mount host filesystems, access kernel features
# Trivial container escape!

Secrets in ENV:

ENV DB_PASSWORD=admin123  # Visible in docker inspect, image layers!
ARG API_KEY=sk_live_xyz   # Build args also visible in image history

# docker inspect --format='{{json .Config.Env}}' container_name
# Returns: ["DB_PASSWORD=admin123", "API_KEY=sk_live_xyz"]

Exposed Docker socket:

docker run -v /var/run/docker.sock:/var/run/docker.sock myapp
# Container can now control the Docker daemon
# Effectively root access to the host!

2 Container Hardening

Apply defense-in-depth to container configurations with non-root users, read-only filesystems, and proper secrets management.

Non-root user in Dockerfile:

FROM node:20-alpine

# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app
COPY --chown=appuser:appgroup package*.json ./
RUN npm ci --production
COPY --chown=appuser:appgroup . .

# Switch to non-root user before CMD
USER appuser
EXPOSE 3000
CMD ["node", "server.js"]

Docker Compose with security options:

services:
  app:
    image: myapp
    security_opt:
      - no-new-privileges:true  # Prevent privilege escalation
    read_only: true             # Read-only filesystem
    tmpfs:
      - /tmp                    # Writable temp area
    environment:
      - APP_ENV=production
    secrets:
      - db_password             # Use Docker secrets, not ENV
secrets:
  db_password:
    file: ./secrets/db_password.txt

Knowledge Check

0/3 correct
Q1

Why is running containers as root more dangerous than running as a non-root user?

Q2

Why should secrets not be stored in Docker ENV environment variables?

Q3

What capability does mounting /var/run/docker.sock inside a container grant?

Code Exercise

Add Non-Root User to Dockerfile

The Dockerfile runs the application as root. Add a non-root user and switch to it before the CMD instruction.

dockerfile