Explain Docker container security: What are the attack vectors and how do you implement defense-in-depth for containers in production?
Quick Answer
Key vectors: vulnerable base images, running as root, exposed Docker socket, privilege escalation, secrets in images. Defense: minimal base images, non-root user, read-only filesystem, seccomp/AppArmor profiles, image scanning in CI.
Detailed Answer
Attack Vectors
1. Vulnerable base images: Unpatched OS packages with known CVEs 2. Running as root: Container processes run as root by default — if container is compromised, attacker has root in the container namespace 3. Docker socket exposure: Mounting /var/run/docker.sock gives full control over the host Docker daemon 4. Secrets in images: API keys, passwords baked into image layers (visible via docker history) 5. Privilege escalation: --privileged flag disables ALL security boundaries 6. Supply chain attacks: Compromised base images or dependencies
Defense-in-Depth Layers
Build Time
- Use distroless or alpine base images (minimal attack surface) - Multi-stage builds: build dependencies don't end up in final image - Scan images with Trivy/Grype in CI pipeline — fail build on critical CVEs - Sign images with Cosign/Notary for supply chain integrity - Never COPY secrets — use build-time secrets (--mount=type=secret)
Runtime
- Run as non-root user: USER 1000:1000 in Dockerfile - Read-only filesystem: --read-only with tmpfs for /tmp - Drop all capabilities, add only what's needed: --cap-drop=ALL --cap-add=NET_BIND_SERVICE - Seccomp profile to restrict syscalls - AppArmor/SELinux for mandatory access control - No --privileged, no --pid=host, no --network=host
Infrastructure
- Don't expose Docker socket to containers - Use rootless Docker or Podman in production - Network segmentation between container workloads - Runtime security monitoring with Falco
Code Example
# Secure Dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build FROM gcr.io/distroless/nodejs20-debian12 WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules USER 1000:1000 CMD ["dist/server.js"] # Secure docker run docker run \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid \ --cap-drop ALL \ --security-opt no-new-privileges \ --user 1000:1000 \ payments-api:2.4.1
Interview Tip
Structure your answer in build-time vs runtime vs infrastructure layers. Mention specific tools (Trivy, Falco, Cosign) and specific flags (--cap-drop ALL, --read-only). This shows production experience, not just theory.