Security
Security capstone: threat-model and harden a web app
Reading about seams is not the same as closing them in a running system. Take a small but realistic web app — login, sessions, an account API, third-party sign-in, a few dependencies — threat-model the whole flow, then harden every layer the track covered and prove each fix with a concrete before/after. This is the audit a senior runs before a launch.
Turn the whole track into one repeatable engineering loop: threat-model a sensitive request end to end, find the seams between correct-looking controls, harden authentication, authorization, token handling, CSRF, password storage, secrets, and the supply chain — and verify each control with evidence, not assertion.
Take a small full-stack web app with login, session auth, a per-user resource API, and at least one OAuth/OIDC sign-in (your own, a deliberately-vulnerable starter like OWASP Juice Shop, or the scaffold below) and produce a threat model plus a hardened build that composes every security-track control — proving each fix with a concrete demonstration.
- The threat-model document maps each control to an OWASP category and explicitly names at least three seams between correct-looking layers (e.g. AuthN-without-AuthZ, HttpOnly-without-CSRF-token, strong-hash-without-rate-limit).
- A demo (script, test, or recording) shows the hardened app: a forged/unsigned JWT rejected, an IDOR attempt denied, a cross-site state-changing request blocked, and a login brute-force throttled — each with the before (vulnerable) behaviour next to the after.
- git log / a secret scan over history shows no live credentials remain in the repo, and the rotation of any previously-committed secret is documented.
- npm audit (or equivalent) plus a committed lockfile and generated SBOM are present; a written note explains how the registry precedence defends against dependency confusion.
- A one-page write-up names, for each layer, the control applied and the seam it closes — framed as the threat model, not a checklist.
- Add an on-call security runbook: how to triage a suspected token theft, an IDOR report, a leaked-secret alert, and a malicious-dependency advisory — with the first containment step for each.
- Add refresh-token rotation with reuse detection, and demonstrate that replaying a rotated refresh token invalidates the session family.
- Add an SSRF guard to any server-side fetch (allowlist outbound hosts, block link-local/metadata ranges) and demonstrate a blocked request to a cloud-metadata endpoint.
- Wire the whole audit into CI as gates: a SAST/dependency-scan job, a secret scanner, and an authz test suite that fails the build if an endpoint is reachable without an ownership check.
This is the audit you run before any real launch: threat-model one sensitive request end to end, then harden every layer the track covered — pin the token’s algorithm and validate iss/aud/exp, enforce object-level deny-by-default authorization, compose HttpOnly + SameSite + a CSRF token and kill XSS at the source, store passwords in a slow salted KDF behind a rate limit, pull every secret out of the repo and rotate what leaked, and lock down the install step against dependency confusion. The discipline is the same throughout: the breach lives in the seam between two correct-looking controls, so you compose them deliberately, apply least privilege to bound the blast radius, and prove each fix with evidence rather than assertion. Doing it once on a small app makes the production version muscle memory.