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

179 lines
4.9 KiB
Markdown

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