# Dockerfile Security Audit **Date:** 2026-02-20 **Auditor:** External Security Review **Scope:** All Dockerfiles in `dockerfiles/` directory ## Executive Summary | Metric | Value | |--------|-------| | Total Dockerfiles Analyzed | 40 | | High Severity Issues | 38 | | Medium Severity Issues | 33 | | Low Severity Issues | 2 | ## Detailed Findings ### 1. Running as Root User (HIGH) **Severity:** HIGH **Affected:** 38 of 40 Dockerfiles (95%) **CWE:** CWE-250 (Execution with Unnecessary Privileges) #### Description The vast majority of Dockerfiles do not include a `USER` directive, meaning containers run as root by default. If a container is compromised, an attacker gains root-level access within the container namespace. #### Affected Files All except: - `dockerfiles/reverse-engineering-assistant/Dockerfile` (creates non-root user) - `dockerfiles/postizz-mcp/Dockerfile` (includes USER directive) #### Recommendation Add non-root user creation and USER directive to all Dockerfiles: ```dockerfile RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser ``` #### Risk Assessment - **Likelihood:** Medium - depends on container escape or service vulnerability - **Impact:** High - root access enables privilege escalation - **Overall:** HIGH --- ### 2. Missing Multi-Stage Builds (MEDIUM) **Severity:** MEDIUM **Affected:** 32 of 40 Dockerfiles (80%) **CWE:** CWE-1026 (Excessive Use of Unmodified Software Components) #### Description Most Dockerfiles use single-stage builds, including build tools and dependencies in the final image. This increases: - Attack surface (more packages = more potential vulnerabilities) - Image size - Build time #### Files Using Multi-Stage Builds (Good) - `dockerfiles/kicad-mcp/Dockerfile` - `dockerfiles/reverse-engineering-assistant/Dockerfile` - `dockerfiles/mongo-mcp/Dockerfile` - `dockerfiles/inspec-mcp/Dockerfile` - `dockerfiles/postgres-mcp/Dockerfile` - `dockerfiles/ssh-mcp/Dockerfile` - `dockerfiles/steam-mcp/Dockerfile` - `dockerfiles/bruno-mcp/Dockerfile` #### Recommendation Convert to multi-stage builds: ```dockerfile # Build stage FROM golang:1.23-alpine AS builder WORKDIR /app COPY . . RUN go build -o myapp # Runtime stage FROM alpine:3.20 COPY --from=builder /app/myapp /usr/local/bin/ ``` --- ### 3. Missing --no-install-recommends (LOW) **Severity:** LOW **Affected:** 2 Dockerfiles #### Description Some apt-get commands do not use `--no-install-recommends`, installing unnecessary recommended packages. #### Affected Files - `dockerfiles/reverse-engineering-assistant/Dockerfile:11` - `dockerfiles/inspec-mcp/Dockerfile:8` #### Recommendation Add `--no-install-recommends` flag and clean up apt cache: ```dockerfile RUN apt-get update && apt-get install -y --no-install-recommends \ package-name \ && rm -rf /var/lib/apt/lists/* ``` --- ### 4. Build-Time Secrets in postizz-mcp (MEDIUM) **Severity:** MEDIUM **Affected:** `dockerfiles/postizz-mcp/Dockerfile` **CWE:** CWE-525 (Use of Web Browser Cache) #### Description The postizz-mcp Dockerfile uses build arguments for API keys: ```dockerfile # Line 36 ARG POSTIZ_WEB_URL=${POSTIZ_WEB_URL} # Line 42 ENV PORT=${PORT} ``` Build arguments can leak secrets into image layers. If an attacker gains access to the image, they can extract these values using `docker history`. #### Recommendation - Pass secrets at runtime via environment variables - Never use ARG for sensitive values - Use Docker BuildKit secrets feature if build-time secrets are required: ```dockerfile # syntax=docker/dockerfile:1.2 RUN --mount=type=secret,id=postiz_token \ export POSTIZ_TOKEN=$(cat /run/secrets/postiz_token) && \ ./configure --token=$POSTIZ_TOKEN ``` --- ## Base Image Analysis ### Images Used | Base Image | Count | Security Status | |------------|-------|-----------------| | alpine:3.20 | 1 | Clean (0 HIGH/CRITICAL) | | python:3.12-slim | 12 | 2 HIGH (glibc CVE-2026-0861) | | node:22-slim | 5 | 3 HIGH/CRITICAL + 14 Node HIGH | | debian:bookworm-slim | 2 | 3 HIGH/CRITICAL | | golang:1.23-alpine | 4 | 6 HIGH/CRITICAL (OpenSSL) | ### Recommendations 1. Pin base images to specific digests for reproducibility 2. Consider Alpine-based images where possible (smaller attack surface) 3. Implement automated base image scanning in CI/CD pipeline --- ## Positive Findings 1. **No hardcoded credentials** in any Dockerfile 2. **Good use of COPY over ADD** (no automatic extraction issues) 3. **Proper WORKDIR usage** (avoids root directory operations) 4. **Some multi-stage builds** implemented correctly 5. **Reasonable base image selection** (official images) --- ## Remediation Priority | Priority | Finding | Effort | Impact | |----------|---------|--------|--------| | 1 | Add USER directive to all Dockerfiles | Low | High | | 2 | Implement multi-stage builds | Medium | Medium | | 3 | Remove build-time secrets | Low | Medium | | 4 | Add --no-install-recommends | Low | Low |