Files
KNEL-AIMiddleware/docs/audit/2026-02-20/01-dockerfile-security.md
Charles N Wyble 787fe1f702 docs(audit): add comprehensive security audit report
External security audit of KNEL-AIMiddleware before release:

- FINAL-REPORT.md: Executive summary, risk assessment, remediation roadmap
- 01-dockerfile-security.md: 38/40 containers run as root (HIGH)
- 02-shell-script-security.md: 83 missing set -e/u directives (HIGH)
- 03-docker-compose-security.md: 3 privileged services documented (MEDIUM)
- 04-secrets-audit.md: PASS - no hardcoded secrets found
- 05-vulnerability-scan.md: 14+ CVEs, 1 CRITICAL OpenSSL (golang:1.23-alpine)

Assessment: CONDITIONAL PASS for release

💘 Generated with Crush

Assisted-by: GLM-5 via Crush <crush@charm.land>
2026-02-20 11:59:09 -05:00

4.9 KiB

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:

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:

# 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:

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:

# 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:
# 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