Software Supply-Chain Security
Software Security · Nutthakorn Chalaemwongwan
Today
- Why the supply chain is now top-tier
- Dependency confusion & typosquatting
- SBOMs, SLSA provenance
- Signing with Sigstore/Cosign
- 🎮 Game: Dependency Confusion Heist
The new #1 design risk
- Your code is ~10% yours, ~90% dependencies
- One bad package → thousands of victims (xz, event-stream, SolarWinds)
- OWASP A03:2025 Software Supply Chain Failures
Real supply-chain attacks
| Case | What happened |
|---|---|
| SolarWinds (2020) | trojanized vendor update → 18k orgs |
| Log4Shell (2021) | RCE in a ubiquitous logging dep |
| event-stream (npm) | malicious dep stole crypto-wallet keys |
| XZ Utils (2024) | backdoor planted in liblzma upstream |
| CircleCI (2023) | stolen CI tokens → customer secrets |
Attacks are shifting upstream: registry → maintainer → CI/CD.
Attack vectors
- Typosquatting —
reqeustsvsrequests; the malicious package'ssetup.pyruns at install time, before any of your code runs — you don't have to import it to be owned - Dependency confusion (CWE-1357) — public pkg shadows internal name
- Malicious updates — compromised maintainer
- Transitive risk — deps of deps you never chose
Try it — which package actually installs?
Set both versions and the index mode. The resolver's real rule decides.
SCA — find vulnerable deps
docker run --rm -v "$PWD:/src" aquasec/trivy fs /src # this lab's Python deps
pip-audit # vs PyPI advisories
- Produces CVEs + fix versions
- CWE-1104 (unmaintained), CWE-829 (untrusted inclusion), CWE-1395 (known-vulnerable 3rd-party dependency)
Integrity: prove what you shipped
- SBOM (CycloneDX/SPDX) — ingredient list of the build
- SLSA — levels of build provenance & tamper-resistance
- A08:2025 Software/Data Integrity Failures
Signing with Cosign (keyless)
IMG=week12-supplychain:lab
docker run --rm -v "$PWD:/src" -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image --format cyclonedx \
--output /src/sbom.cdx.json "$IMG" # SBOM
docker run --rm -e COSIGN_EXPERIMENTAL=1 \
-v /var/run/docker.sock:/var/run/docker.sock \
gcr.io/projectsigstore/cosign:latest sign --yes "$IMG" # sign (OIDC)
docker run --rm -e COSIGN_EXPERIMENTAL=1 \
-v /var/run/docker.sock:/var/run/docker.sock \
gcr.io/projectsigstore/cosign:latest verify \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer-regexp ".*" "$IMG" # verify
- Unsigned/tampered image → verification fails
- Every step needs the docker-socket mount (trivy has to reach the local image, not just a local dir) — the SBOM step is a common copy-paste failure if it's dropped
cosign verifyneeds the two--certificate-*-regexpflags in keyless mode — without them it errors, it doesn't just "fail closed"- Keyless signing is backed by Fulcio (short-lived cert authority) + Rekor (public transparency log) — no long-lived private key sitting on disk to leak (CWE-321)
Tooling — GitHub Advanced Security (GHAS)
- Secret scanning + push protection — block secrets at push time (before they reach the remote)
- CodeQL code scanning — semantic SAST queries
- Dependabot — alerts + auto-PRs for vulnerable deps
- Native in the repo → results in the Security tab
Defenses
pip install --require-hashes— a substituted package's hash won't match; install refuses- Single
--index-url, not--extra-index-url— one trusted index; the resolver won't "shop around" and pick a higher-versioned public package over your internal one - Verify signatures before deploy (admission policy)
- Generate + store SBOMs per release
- 2FA/MFA on dev/CI/cloud accounts; least privilege
- Automate SCA in CI (next week)
The whole journey, one dependency
📦 Game — Dependency Confusion Heist
- Attack: no live registry in this lab — use the resolver simulation to watch a higher-version public pkg beat the private one
- Defend: pin + scope; generate SBOM; sign & verify with Cosign; add a provenance gate
Deliverable
📋 Worksheet 12 —
labs/week12-supply-chain/worksheet.md(Parts 1–4) · kickoff:bash sca_scan.sh(trivy fs + pip-audit)
- SCA report + remediation plan (Part 3)
- SBOM file + sign/verify transcript (Part 3)
- One-paragraph SLSA self-assessment + XZ Utils case analysis (Part 4)
- + Audit the AI / EiPE / Prompt Problem (required, after Part 4 — see worksheet)
Key takeaways
- Most of your attack surface is other people's code
- Know your ingredients (SBOM), prove your build (SLSA), sign your artifacts
- Verify before you trust
Questions?
Next week: Cloud & container security