Security Deep Dive

Threat Modeling — Find the Bugs on the Whiteboard

Threat modeling is a structured conversation about what could go wrong. Done before code, it surfaces design-level security bugs that no scanner can catch. Done well, it costs an hour and saves a quarter.

STRIDEAttack TreesFour QuestionsTrust Boundaries
← Back to Security
Quick Facts

The Four-Question Frame

Adam Shostack's "four-question frame"

  • What are we working on? Draw it. A whiteboard sketch is plenty.
  • What can go wrong? Walk the diagram, ask "what's the worst that could happen here?"
  • What are we going to do about it? Mitigations, accepted risks, decisions to defer.
  • Did we do a good job? Validate later — bug bounty hits, pen-test findings, real incidents tell you.

If you remember nothing else, remember those four questions. The frameworks below are tools that help you answer them.

Step 1

Diagram the System

Use a Data-Flow Diagram (DFD). Five primitives is enough:

  • External entities — users, third-party services. Things you don't control.
  • Processes — your code: API server, worker, frontend.
  • Data stores — databases, caches, queues, S3 buckets.
  • Data flows — arrows showing what data moves where.
  • Trust boundaries — dotted lines wherever the level of trust changes (internet ↔ your VPC, your VPC ↔ DB subnet, your service ↔ a vendor API).

Most interesting threats live on the trust boundaries. Mark them clearly.

Step 2

STRIDE — A Threat Per Letter

For every element in the diagram, walk the six STRIDE categories. Microsoft's mnemonic, still the best general-purpose checklist.

LetterThreatDefendsExample
SSpoofingAuthenticationAttacker forges a session, replays a JWT, impersonates a service.
TTamperingIntegrityModifying data in transit, in storage, or in flight (e.g., bypassing client-side validation).
RRepudiationNon-repudiation / AuditUser denies an action; logs are missing or unreliable.
IInformation DisclosureConfidentialityIDOR, verbose errors, S3 misconfig, leaky logs.
DDenial of ServiceAvailabilityResource exhaustion, billion-laughs XML, slow loris, expensive query oracle.
EElevation of PrivilegeAuthorizationMass assignment, missing role check, privilege escalation via shared key.

Not every letter applies to every element — but the discipline of asking each one prevents tunnel vision.

Other Frameworks

Beyond STRIDE

FrameworkBest for
STRIDEDefault checklist for app teams; simple, well-known.
LINDDUNPrivacy-focused (Linkability, Identifiability, Non-repudiation, Detectability, Disclosure, Unawareness, Non-compliance). Use when GDPR-style risks dominate.
PASTAProcess for Attack Simulation & Threat Analysis — heavier, business-risk-driven, suits enterprise.
Attack TreesPick a goal ("steal user data"), branch downward through how an attacker would achieve it. Great for high-value flows.
MITRE ATT&CKCatalog of real-world adversary tactics. Useful for ops/red-team threat modeling more than design-time.
OWASP Threat Dragon / Microsoft Threat Modeling ToolIf you want a tool. Most teams do fine with a whiteboard and a doc.
Step 3

Mitigations & Decisions

For each threat you find, pick one:

  • Mitigate. Add a control — input validation, rate limit, RBAC check, encryption.
  • Eliminate. Redesign the feature so the threat doesn't exist (the strongest mitigation).
  • Transfer. Hand the risk to someone better at handling it (use a managed identity provider, not your own).
  • Accept. Document the residual risk and who signed off. Real and legitimate — not every theoretical issue is worth fixing.

Track decisions as ADRs. The "why we didn't fix this" record matters as much as the "what we fixed" record.

When

Where Threat Modeling Fits

  • New feature design. The highest-leverage moment. One hour with the design doc.
  • Architecture changes. New service, new data store, new vendor.
  • Trust-boundary changes. Anything that exposes a previously internal surface.
  • Periodic review. Annually or after major releases — the system has drifted from last year's diagram.
  • After incidents. Update the model with what you learned.

It doesn't need to be heavyweight. A 60-minute "evil brainstorm" with the team beats a 200-page document nobody reads.

Worked Example

Threat Model — URL Shortener Redirect Path

System sketch

User → CDN → Redirect API → Cache (Redis) → DB (Postgres). Redirect API also fetches the target URL on creation to extract the page title (preview feature).

Trust boundaries

  • Internet ↔ CDN edge.
  • CDN ↔ Redirect API (origin).
  • Redirect API ↔ Redis & Postgres (private subnet).
  • Redirect API ↔ third-party target URL (egress fetch).

STRIDE walk (abridged)

ElementThreatMitigation
Create-link APIS — anonymous abuse to mass-create spam linksRate limit per IP + per anon quota; CAPTCHA over threshold; abuse domain deny-list.
Create-link APII — preview-fetch makes server-side requests (SSRF)Resolve hostname; reject private/loopback/link-local; scheme allow-list (http/https); egress proxy with allow-list.
RedirectT — open-redirect abuse (phishing through your domain)Show preview interstitial for low-reputation domains; deny-list known phishing/malware sources.
RedirectD — viral link DDoSing originCDN caches 302s; rate limit at edge; circuit breaker on DB; degrade to read-only on overload.
Stats endpointE — IDOR: any user reads any link's statsOwnership check; partial index keyed on owner; Postgres RLS as defense in depth.
Click eventsR — disputed clicks (analytics fraud)Sign click events; correlate IP + UA + timestamp; rate-limit click writes per IP.

Decisions

  • Mitigate: rate limit, SSRF defenses, ownership checks, CDN caching, RLS.
  • Accept: sophisticated click fraud — out of scope for v1; revisit after launch metrics.
  • Transfer: phishing reputation handled via a third-party domain reputation API rather than building our own.
Tips

Make It Stick

  • Time-box it. 60 minutes per feature, 2 hours for a big architecture change.
  • Small group. 2–4 people: an engineer who knows the design, an engineer who likes breaking things, optionally security and ops.
  • Adversarial mindset. Pretend you're the attacker. "If I owned that key, what could I do?"
  • One page of output. Diagram + STRIDE table + decisions + owners. If it's longer, nobody re-reads it.
  • Treat it as a living doc. Update on architecture changes; don't let it bit-rot.
  • Don't aim for "all threats found". Aim for the high-impact ones that the team can act on this sprint.
Continue

Related Reading