Image uses multi-stage builds to minimize final layer size
Why it matters
Single-stage Docker builds include compilers, package managers, build caches, test fixtures, and development dependencies in the final production image. Every extra binary is an additional attack surface — a compromised container with build tools installed can compile exploits, exfiltrate files, or pivot to other services more easily. NIST 800-53 CM-7 requires systems to provide only essential capabilities. CIS Docker 4.9 explicitly requires minimal image construction. Images over 500 MB also inflate registry storage costs and slow deployment velocity at scale.
Severity rationale
High because bloated images increase attack surface by including compilers and dev tools that have no role in production and enable post-compromise lateral movement.
Remediation
Separate build and runtime stages in Dockerfile to exclude all build tooling from the final image:
# Stage 1: compile
FROM node:20 AS builder
WORKDIR /build
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: runtime only
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /build/dist ./dist
COPY --from=builder /build/node_modules ./node_modules
USER 1001
CMD ["node", "dist/index.js"]
For Go or compiled binaries, the final stage can be FROM scratch or FROM gcr.io/distroless/static, reducing runtime images to under 20 MB.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Infrastructure Hardening Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- nist:rev5 · CM-7 — Least Functionality
- external · CIS-Docker-4.9 — CIS Docker Benchmark v1.6 §4.9 — Use multi-stage builds
- iso-25010:2011 · security-maintainability — Maintainability / Security via reduced attack surface
Taxons
History
- 2026-04-18·v1.0.0·Initial import from infrastructure-hardening·automated