Skip to main content

All weeks · Worksheet · Overview · Hardening notes

Week 13 · Lecture slides

Week 13

Contents14 sections

Cloud & Container Security

Software Security · Nutthakorn Chalaemwongwan


Today

  • Shared-responsibility model
  • IAM & least privilege
  • Secrets management
  • Container/image hardening
  • 🎮 Game: Misconfig Hunt

Recap & framing

  • Supply chain → what you build with
  • Today → where you run it
  • OWASP A02:2025 Security Misconfiguration (now #2)

Shared responsibility

  • Cloud secures of the cloud; you secure in the cloud
  • Misconfig — not provider bugs — causes most breaches
  • Defaults are rarely safe

IAM & least privilege

{ "Effect":"Allow", "Action":"*", "Resource":"*" }   // 🚩
  • Over-broad policies = blast radius
  • Resource:"*" → CWE-732 (incorrect permission assignment); Action:"*" → CWE-269 (improper privilege management) — they're graded as two distinct findings on the same policy, not one
  • Fix: scope to one bucket + one action, add a Condition (e.g. s3:prefix) — not just a narrower ARN
Two findings, one statement: Action vs Resource wildcards (Week 13) — open full size

Secrets management

  • Secrets in env vars / Dockerfile / git = leaked
  • Use a secrets manager / vault; rotate
  • Scan history (Gitleaks) — recall Week 2

Storage & network exposure

  • Public buckets, open ports, default creds
  • Encrypt at rest + in transit
  • Private by default; explicit allow

Container image hardening

docker run --rm -v "$PWD:/src" aquasec/trivy config /src                    # misconfig
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image week13-hardened:lab                              # image CVEs
  • Multi-stage build: python:3.11-slim@sha256:... (compiles) → distroless gcr.io/distroless/python3-debian12@sha256:... (runs) — a smaller runtime image with no shell/package manager, USER 65532:65532 (non-root)
  • @sha256:... digest pins, not just a version tag — a tag can be repointed later, a digest can't
  • Re-scan to prove reduced findings
  • Trivy only catches 3 of 6 planted defects (:latest, root user, secret-in-ENV) — COPY . ., chmod -R 777, and unpinned pip install need manual review, no rule fires

Kubernetes basics (awareness)

  • Pod security, network policies, RBAC
  • Don't run privileged; limit service-account tokens

Same app, shipped twice

The same app as two container images side by side, insecure vs hardened, six layers compared: mutable :latest tag vs a pinned digest, a baked-in secret vs runtime injection, root user vs distroless non-root, COPY-everything vs a minimal context, world-writable permissions vs read-only, and an unpinned pip install vs a discarded build stage. Below both, the same argument one layer up: the wildcard IAM policy vs the scoped one. The conclusion: Trivy flags only three of the seven defects shown here — the tag, the root user, and the secret. COPY .., chmod 777, the unpinned install, and the IAM JSON all need manual review; there is no rule for any of them.


🔍 Game — Misconfig Hunt

9 flags — each misconfiguration found + explained = a flag:

  1. Container (6): :latest tag, root user, secret-in-ENV, COPY . ., chmod -R 777, unpinned pip install
  2. IAM (3): Resource:"*" (CWE-732), Action:"*" (CWE-269), missing Condition scoping

Deliverable

📋 Worksheet 13 — labs/week13-cloud-container/worksheet.md (Parts 1–4) · kickoff: bash scan.sh (trivy config over the Dockerfiles only — IAM JSON is manual review, Trivy doesn't parse it)

  • Before/after IAM policy + Dockerfile, all 9 flags explained
  • Trivy reports showing reduced risk (container half only)
  • Note on secrets remediation
  • + Audit the AI / EiPE / Prompt Problem (see worksheet)

Key takeaways

  • Misconfiguration > zero-days as a breach cause
  • Least privilege, private-by-default, no secrets in code
  • Scan IaC and images in CI

Questions?

Next week: AI / LLM application security

All weeks in Software Security