Week 12 · worksheet

Worksheet 12 — Software Supply-Chain Security (3 hrs)

← all weeks · readme · dependency-confusion · slides

Worksheet 12 — Software Supply-Chain Security (3 hrs)

Course: Software Security (KOSEN69) · Week 12 Aligned: OWASP 2025 — A03 Software Supply Chain Failures · A08 Software or Data Integrity Failures · CWE: CWE-1104, CWE-829, CWE-1357, CWE-1395 Signature game: 📦 Dependency Confusion Heist Ethics note: The dependency-confusion / typosquat exercise runs only against the instructor-provided private registry in the isolated lab network (dependency-confusion.md). Never plant or publish look-alike packages on the real PyPI or npm — that is an attack on every downstream user.

Part 1 — Student Information

NameStudent IDDateGroup

Part 2 — Lecture Questions

  1. Explain dependency confusion (substitution). Why does a public acme-internal-utils==99.0.0 win over a private ==1.4.0 when a resolver shops both indexes?
  2. How does typosquatting (reqeusts, urlib3) achieve code execution at install time before any of your code runs?
  3. What is an SBOM (CycloneDX/SPDX) and why is it a prerequisite for both incident response and SLSA provenance?
  4. Sigstore keyless signing uses Fulcio (CA) + Rekor (transparency log) tied to an OIDC identity. Why is that safer than a long-lived private key (CWE-321)?
  5. Summarize the SLSA levels. Which level does "signed artifact + SBOM + provenance gate before deploy" put you at, and what is still missing?

Part 3 — Hands-on Lab (150 min)

Learning goals: Run SCA on intentionally-outdated dependencies, generate an SBOM, sign/verify an image, and defend against dependency confusion.

Prerequisites: Docker; the lab folder (requirements.txt, Dockerfile, app.py, sca_scan.sh, sign.sh). For signing: browser for the OIDC flow + registry push access.

Environment setup

cd labs/week12-supply-chain
bash sca_scan.sh                 # trivy fs + pip-audit on requirements.txt (+ optional image scan)
docker build -t week12-supplychain:lab .
bash sign.sh week12-supplychain:lab   # CycloneDX SBOM -> sbom.cdx.json, then cosign sign + verify

What to submit per task: the exact command(s) + output, a screenshot, and a 2–3 sentence remediation note mapping the finding to A03/A08 or the CWE.

Task 0 — Onboarding (15 min)

Read requirements.txt and list the pinned packages with their versions. Note why they are intentionally outdated (each is deliberately an old release so SCA tools flag its known CVEs). Deliverable: the package/version table + which OWASP/CWE this maps to.

Task 1 — SCA scan: build the remediation worklist (35 min)

Goal: Flag the known-vulnerable dependencies — A03. Steps:

  1. bash sca_scan.sh — read the trivy fs table (CVE, installed vs. fixed version) and the pip-audit advisory IDs (GHSA-/PYSEC-).
  2. Pick three findings; record CVE/advisory id, severity, and the fixed version.

Deliverable: the SCA output + a 3-row remediation table (package → current → fixed).

Task 2 — Dependency Confusion Heist (35 min)

Goal: Watch the wrong package win — A03 / CWE-1357. **Steps (against the lab's private + "public" indexes, per dependency-confusion.md):**

  1. pip install -v acme-internal-utils and note the source URL/version served.
  2. Re-resolve so the higher-versioned public look-alike (==99.0.0) wins; observe the PWNED.txt marker proving install-time code ran.

Deliverable: the source URL/version before vs. after confusion + the marker proof.

Task 3 — SBOM + signing/verification (30 min)

Goal: Produce a component inventory and prove integrity — A08. Steps:

  1. After bash sign.sh week12-supplychain:lab, open sbom.cdx.json and find Flask's entry.
  2. Read the cosign verify PASS for the signed image.
  3. Negative test on an unsigned image (it must fail):

cosign verify --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*' python:3.9-slimError: no signatures found. (Both --certificate-identity* flags are required in keyless mode; without them cosign stops at Error: --certificate-identity or --certificate-identity-regexp is required — a usage error, which is not the same thing as proving the image is unsigned.) Deliverable: the SBOM Flask component entry + the verify PASS + the negative-test failure.

Task 4 — Defend / fix it (35 min)

Goal: Stop dependency confusion and lock integrity — defenses from dependency-confusion.md + sign.sh. Steps:

  1. Pin + hashes: convert to pip install --require-hashes -r requirements.txt (or a committed lockfile); re-run Task 2 step 2 and show a hash mismatch blocks the substitution.
  2. Single trusted index: use one --index-url instead of --extra-index-url; explain why the resolver stops shopping around.
  3. Namespace scoping: describe reserving/namespacing the internal package name.
  4. Provenance gate: state how the cosign verify from sign.sh becomes a gate before a simulated deploy.

Deliverable: before/after of which registry served the package + the one defense you found most effective and why.

Part 4 — Reflection

  1. Mapping: table — finding | tool (sca_scan.sh / sign.sh) | OWASP 2025 id | CWE | fix.
  2. Real breach: analyze the XZ Utils backdoor (CVE-2024-3094). Which OWASP/CWE applies, and would an SBOM + signing + provenance gate have caught a maliciously-modified upstream dependency? (Compare with SolarWinds or Log4Shell if useful.)
  3. Best mitigation + SLSA self-assessment: one paragraph — which SLSA level your defenses reach and why, and the single highest-leverage control for your team.

Grading rubric (100)

CriterionWeight
Lecture questions (Part 2)20
Exploitation + evidence (Tasks 1–3: SCA findings, confusion proof, SBOM/verify)40
Defense (Task 4: pinning/hashes, single index, scoping, provenance gate)25
Reflection (Part 4: mapping, XZ breach, SLSA self-assessment)15
Total100

Evidence & Integrity (required)

  • Identity proof: every screenshot/diagram must show your **whoami / login email / student ID and a timestamp**. Generic or borrowed evidence is not accepted.
  • Personalized flag (if this lab issues one): ____________________

Flags are unique per student — submitting another student's flag is a violation. See SUBMISSION.md.

  • Explain in your own words (graded on your reasoning, not copied text):
  1. What did you do, and why did the vulnerability work?
  2. Why does your fix actually stop it — and what could still break it?

🤖 Audit the AI (required)

AI is a power tool you must distrust — you are graded on your critique, not the AI's answer.

  1. Ask an AI assistant to exploit or fix this week's vulnerability. Paste its full answer.
  2. Find what's wrong or risky in it — insecure code, a subtly incomplete fix, a hallucinated API/function/CVE, a missed edge case, or wrong reasoning. Quote the exact line(s).
  3. Produce the correct, verified version yourself and explain in 2–3 sentences why the AI's output was insufficient.

Disclose your AI use in the Part 1 table. This task counts toward your Defense + Reflection score.


🧠 Comprehension & Prompt (required)

A. Explain in Plain English (EiPE). In 2–3 sentences, in your own words, describe what this week's vulnerable code/endpoint actually does and why it is exploitable — explain the mechanism, don't dump jargon.

B. Prompt Problem. Write a single prompt that makes an AI produce a correct, secure fix for one finding. Run it: does the exploit now fail? If not, refine the prompt and try again. Submit the final prompt + the verified result. Graded on the prompt's precision and your verification — this trains problem decomposition and AI literacy (Denny et al. 2024).