Cloud & Container Security
Software Security · Nutthakorn Chalaemwongwan
Today
- Shared-responsibility model
- IAM (who can do what) & 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
- The provider secures the cloud itself; you secure what you put in it
- Misconfig — not provider bugs — causes most breaches
- Defaults are rarely safe
Whose job is it?
IAM & least privilege
{ "Effect":"Allow", "Action":"*", "Resource":"*" } // 🚩
- Read a statement as: Effect (allow or deny) · Action (what) · Resource (on which thing) · Condition (only when …)
Resource:"*"→ CWE-732,Action:"*"→ CWE-269: graded as two findings on the same policy- Fix: use two statements for one bucket. Allow
s3:GetObjectonapp/*. Allows3:ListBucketonly when thes3:prefixConditionmatchesapp/*
If the key leaks — blast radius
Secrets management
- Secrets in env vars / Dockerfile / git = leaked
- Use a secrets manager / vault; rotate
- Scan history (Gitleaks) — recall Week 2
Where the ENV secret ends up
Try it — which layer gives it away?
Real docker history / docker inspect output from both lab images. Start with docker history --no-trunc and compare the ENV rows.
Storage & network exposure
- Public buckets, open ports, default creds
- Encrypt at rest + in transit
- Private by default; explicit allow
Container image hardening
# 1. Dockerfile misconfigs 2. known CVEs in the built image
docker run --rm -v "${PWD}:/src" aquasec/trivy:latest \
config --severity MEDIUM,HIGH,CRITICAL /src
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image --severity HIGH,CRITICAL week13-hardened:lab
- Two stages: build in
python:3.11-slim, run in distroless (no shell, no package manager) as user65532, not root - Pin by digest (
@sha256:...): a tag can be moved later, a digest cannot - Trivy finds only 3 of the 6 defects.
COPY . .,chmod -R 777and unpinnedpip install: read the file
Does Trivy see it?
Start with fix only what Trivy flags: Trivy says 0, but 3 defects are still in the file. Then fix the rest one at a time.
Kubernetes basics (awareness)
- Pod security (a pod = one or more containers run together), network policies, RBAC (role-based access control)
- Don't run privileged; limit service-account tokens
Same app, shipped twice
🔍 Game — Misconfig Hunt
9 flags — each misconfiguration found + explained = a flag:
- Container (6):
:latesttag, root user, secret-in-ENV,COPY . .,chmod -R 777, unpinnedpip install - IAM (3):
Resource:"*"(CWE-732),Action:"*"(CWE-269), missingConditionscoping
Deliverable
📋 Worksheet 13 —
labs/week13-cloud-container/worksheet.md(Parts 1–4) · start:bash scan.sh(it scans the Dockerfiles only — read the IAM JSON yourself)
- Before/after IAM policy + Dockerfile, all 9 flags explained
- Trivy results before/after (container part only)
- A short note: how to remove and rotate the leaked secret
- + 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 infrastructure-as-code (IaC) files and images in CI
Questions?
Next week: AI / LLM application security