Frontend Labs
⋯

Chapter 52 — Threat modeling and secure design

In one sentence

Threat modeling is a structured conversation, held before you build, about what you're building, what can go wrong, and what you'll do about it — and it's the cheapest security activity per bug prevented.

The four questions (Shostack's framework)

   1. WHAT ARE WE BUILDING?      a diagram: components, data stores, data
                                 flows, and TRUST BOUNDARIES (where data
                                 crosses from less- to more-trusted, or
                                 between owners). Keep it simple -- a
                                 whiteboard DFD, not a 40-page doc.
   2. WHAT CAN GO WRONG?         enumerate threats against each element and
                                 each flow crossing a boundary (use STRIDE
                                 as a prompt).
   3. WHAT ARE WE GOING TO DO?   for each threat: MITIGATE (add a control),
                                 ELIMINATE (remove the feature/data),
                                 TRANSFER (someone else's problem -- e.g.
                                 use a managed service), or ACCEPT
                                 (document, with sign-off).
   4. DID WE DO A GOOD JOB?      review it; revisit when the design changes;
                                 check the mitigations actually shipped and
                                 have tests.

STRIDE — a checklist for "what can go wrong"

   S  Spoofing              pretending to be someone/something
        -> authentication (Ch 46), mTLS (Ch 31), signed messages (Ch 21)
   T  Tampering             unauthorised modification of data/code
        -> integrity: AEAD (Ch 15), HMAC/signatures, input validation,
           access control (Ch 45), signed artifacts (Ch 47)
   R  Repudiation           "I didn't do that" (and you can't prove otherwise)
        -> audit logging (Ch 50), signatures/non-repudiation (Ch 21)
   I  Information disclosure exposure of data to the wrong party
        -> encryption in transit/at rest, least privilege, redaction,
           avoiding verbose errors, minimising data collected
   D  Denial of service     making it unavailable
        -> rate limiting, quotas, timeouts, autoscaling, input-size caps,
           algorithmic-complexity review, CDN/anti-DDoS
   E  Elevation of privilege gaining capabilities you shouldn't have
        -> authz on every request (Ch 45), sandboxing, least privilege,
           memory-safe languages / careful native code, no injection (Ch 42)

   Walk each component and data flow, ask "how could each letter apply
   here?" -- STRIDE is a creativity prompt, not a compliance form.

Other lenses you can layer in: attack trees (goal → sub-goals), LINDDUN (privacy threats), abuse/misuse cases, kill-chain / MITRE ATT&CK (how a real adversary would progress), and "what would a malicious insider do?".

Secure-design principles (Saltzer & Schroeder, still current)

   Least privilege            minimum rights, minimum time
   Fail-safe defaults          deny by default; errors deny access (Ch 3:
                               fail-closed vs fail-open -- choose per context)
   Defense in depth            no single control is trusted to hold
   Complete mediation          check EVERY access, every time (no caching a
                               stale "yes" -- Ch 45)
   Economy of mechanism        keep the security-critical part small and
                               simple enough to audit
   Open design                 security from keys/config, not secrecy of
                               design (Kerckhoffs, Ch 12)
   Separation of privilege      require two conditions (MFA, 4-eyes on
                               deploys, split keys)
   Least common mechanism       don't share state/resources across trust
                               levels (multi-tenant isolation)
   Psychological acceptability   if it's too painful, people bypass it ->
                               design the secure path to be the easy path
   Minimise attack surface      fewer endpoints, features, deps, ports, data
   Secure the weakest link      attackers target it; find yours

The SecureShop threat model (the Chapter 4 payoff)

Chapter 4 asked you to write down your instincts for four questions. Here's the worked answer, as a threat model. Compare it to what you wrote.

   SYSTEM (DFD, simplified):

     [Customer browser] --HTTPS--> (TB1) [edge/nginx] --> (TB2) [web/API]
                                                              |
                                              (TB3)  --mTLS-->[orders-api]
                                                              |
                                              (TB4)  -------->[PostgreSQL]
     [Admin browser] --HTTPS+mTLS--> (TB1') [admin app] --(TB3)--> orders-api
     [CI/CD] --signed artifact--> (TB5) [deploy] --> web/API, orders-api

   TRUST BOUNDARIES: TB1 internet->DMZ, TB2 DMZ->app, TB3 service->service,
   TB4 app->data, TB5 build->runtime, plus browser<->server (attacker owns
   the client).

   THREATS (STRIDE, selected) and DECISIONS:

   PASSWORD STORAGE  (your Ch 4 instinct: ______)
     T/I: DB theft -> offline cracking.
     -> Argon2id, per-user salt, pepper in KMS (Ch 10). MFA available;
        passkeys roadmap (Ch 46). Breached-password screening. ACCEPT
        residual risk of weak user passwords, mitigated by MFA + rate limit.

   KEY STORAGE  (your Ch 4 instinct: ______)
     I/E: JWT signing key, DB creds, TLS private keys.
     -> Secrets manager; workload identity; no secrets in repo/image
        (Ch 49). 2-versions-live rotation runbook, tested. TLS keys
        non-exportable where possible.

   PER-CUSTOMER AUTHZ  (your Ch 4 instinct: ______)
     E/I: IDOR on /orders/:id, /baskets/:id; horizontal escalation.
     -> Ownership in the WHERE clause on every query; centralised policy
        layer; 404 not 403; automated "as another user" tests (Ch 45).
        Object IDs are UUIDv4 (defence in depth, not the control).

   PRICE / TOTAL TAMPERING  (your Ch 4 instinct: ______)
     T: client submits price/total/discount.
     -> Server recomputes every monetary value from DB prices; coupons
        validated server-side; ignore client-supplied totals entirely.
        Idempotency keys + row locks on checkout to kill race conditions
        (Ch 45, insecure design).

   OTHER NOTABLE:
     S  admin impersonation      -> admin app requires mTLS + SSO + MFA;
                                    short sessions; admin actions logged &
                                    alerted (Ch 50).
     T  supply-chain             -> SBOM + scan + signed images verified at
                                    deploy; Actions pinned to SHA (Ch 47).
     R  "I didn't refund that"   -> immutable audit log of all admin/money
                                    actions (Ch 50).
     I  SSRF from "import from URL"-> allowlist + post-resolution IP check;
                                    IMDSv2; isolated egress (Ch 44).
     D  checkout/login flooding  -> rate limits per-account & per-IP; WAF;
                                    CDN; input-size caps.
     E  container breakout       -> non-root, read-only FS, seccomp,
                                    dropped caps, segmented network (Ch 39).

   RESIDUAL RISKS (accepted, with owner + review date): weak user
   passwords (mitigated), a rogue CA issuing for our domain (detected via
   CT monitoring, Ch 30), a determined malicious insider with DB access
   (mitigated by logging + separation of duties, not eliminated).

When and how to do it (lightweight, continuous)

   * At design time for anything new or significantly changed. 60-90 min,
     the team + a security-minded facilitator, a whiteboard.
   * "Threat model every story" for high-risk components: a 2-line
     "security notes" field in the ticket.
   * Keep the artifact IN THE REPO (docs/threat-model.md + the diagram as
     code -- e.g. `pytm`, Threagile, or just Mermaid). Review it in PRs
     that change the design.
   * Track mitigations as issues; verify they shipped with tests.
   * Re-run after incidents (a real attack is ground truth).

Practice / capstone (90 min): threat-model your own project

   1. Pick a real system you work on (or SecureShop).
   2. Draw the DFD: components, data stores, flows, trust boundaries.
      (Whiteboard photo, or Mermaid, or `pytm`.)
   3. For each element and each flow crossing a boundary, run STRIDE.
      Aim for ~15-30 concrete threats.
   4. For each threat, decide: mitigate / eliminate / transfer / accept.
      Name the control and where it lives in this guide.
   5. List residual/accepted risks with an owner and a review date.
   6. Cross-check against the secure-design principles list -- any
      violated? (Shared DB creds across services? A cached authz "yes"?
      A security check that's easy to skip?)
   7. Produce docs/threat-model.md + diagram, and open issues for the
      top 5 unmitigated threats.
   8. Compare with your Chapter 4 notes: what did you get right by
      instinct, and what did this guide change?

Common confusions

  • "Threat modeling needs a specialist and weeks." A team with a whiteboard and the four questions produces most of the value in 90 minutes. Depth comes with practice.
  • "STRIDE is a compliance checklist." It's a prompt for imagination against each component. The output is threats and decisions, not a filled form.
  • "We did it once." Designs change; threat models are living docs, reviewed when architecture changes and after incidents.
  • "We'll accept that risk" (verbally)." Accepted risk must be written, with an owner and a review date, and visible to someone accountable. Otherwise it's just an unfixed bug.
  • "Secure design is about adding controls." Often the best move is elimination — don't collect the data, don't expose the endpoint, use a managed service — which removes the threat instead of guarding it.

Check yourself

  1. State Shostack's four questions.
  2. Expand STRIDE and give one mitigation for each letter.
  3. What is a trust boundary, and why do threats cluster at them?
  4. Name five Saltzer & Schroeder principles and what each means in one line.
  5. For SecureShop's "client submits the price" threat, what's the fix, and which STRIDE letter(s) is it?
  6. What are the four possible decisions for a given threat?

Further reading

  • Book: Threat Modeling: Designing for Security, Adam Shostack — the standard text. Also his free "Threat Modeling 101" resources and the Threat Modeling Manifesto (threatmodelingmanifesto.org).
  • Paper: Saltzer & Schroeder, "The Protection of Information in Computer Systems" (1975) — the design principles, still quoted 50 years on.
  • Tools: Microsoft Threat Modeling Tool; OWASP pytm (threat model as code); Threagile; OWASP Threat Dragon (free, diagram-based).
  • Cheat sheet: OWASP "Threat Modeling Cheat Sheet" and "Secure Product Design Cheat Sheet".
  • Privacy lens: LINDDUN (linddun.org) for privacy threat modeling.

End of Part 11 — Milestone check

  • I can list where secrets leak and order storage approaches best→worst
  • I set up secret scanning + push protection and issued a dynamic, short-lived credential
  • I can describe the 2-versions-live rotation pattern and have tested one
  • I know what to log, what never to log, and why logs must be central and append-only
  • I built a detection baseline: schema, rules with runbooks, simulated attacks, measured MTTD
  • I can recite the IR lifecycle and know preparation is most of it
  • I know the containment trade-offs and the order of volatility
  • I ran an IR tabletop end to end and wrote it up
  • I can run a STRIDE threat model against a real system
  • I produced a threat model for my own project and compared it to my Chapter 4 instincts

Generated from real-life-guide.md · 8 Oct 2026 16:36