Week 13 · harden

Hardening Checklist — Misconfig → Fix

← all weeks · worksheet · readme · slides

<!-- Sandbox/teaching only; for authorized lab use. -->

Hardening Checklist — Misconfig → Fix

OWASP 2025: A02 Security Misconfiguration · CWE: CWE-732, CWE-16, CWE-250, CWE-798

Run ./scan.sh against the insecure artifacts, fix each row, then re-run to watch the findings disappear.

Container image (Dockerfile.insecureDockerfile.hardened)

#Misconfiguration (insecure)CWEFix (hardened)
1FROM python:latest (unpinned, mutable)CWE-1104 / CWE-16Pin to a digest (@sha256:...); use a slim/distroless base
2Secret in ENV API_TOKEN=...CWE-798 / CWE-200No secrets in image. Inject at runtime via secrets manager / mounted secret
3COPY . . (whole context)CWE-538Copy only needed files; add a .dockerignore (exclude .git, .env, keys)
4chmod -R 777 /appCWE-732Default perms; app owned by non-root, not world-writable
5Runs as root (no USER)CWE-250USER 65532:65532 (non-root); distroless nonroot
6Unpinned pip installCWE-1104Pinned requirements.txt (+ hashes) in a build stage

Extra runtime hardening (not in the Dockerfile, enforce at deploy)

  • docker run --read-only --cap-drop ALL --security-opt no-new-privileges
  • Set resource limits (--memory, --pids-limit) to blunt DoS.
  • Never --privileged; never mount the Docker socket into untrusted containers.

IAM (iam-policy-insecure.jsoniam-policy-leastpriv.json)

#MisconfigurationCWEFix
7"Action": "*"CWE-269Enumerate only the actions used (e.g. s3:GetObject)
8"Resource": "*"CWE-732Scope to specific ARNs (one bucket + prefix)
9No conditionsCWE-732Add Condition (e.g. s3:prefix, source IP, MFA)

Principle

Least privilege + shared responsibility: grant the minimum, on the minimum, under the right conditions. The cloud provider secures of the cloud; you secure what you put in it.

Deliverable

Before/after scan.sh output (finding counts) + the diffed policy and Dockerfile, with one sentence per fix on why it reduces risk.