The Engineering Codex/Application Security Engineering
DAY 1 · PM
02 / 09

Threat Modeling — STRIDE, Trust Boundaries & Attack Trees

schedule6 minsignal_cellular_altBeginner1,226 words
Stop guessing where the bugs are. Threat modeling is the structured habit of asking — for every component you ship — what could go wrong, who would do it, and what stops them.

What you will learn

01Step 1 — Diagram the System
02Step 2 — STRIDE, the Threat Catalogue
03Step 3 — Run STRIDE on Each Element
04Step 4 — Worked Example: A Login Endpoint
05Step 5 — Risk-Rank with DREAD or Likelihood × Impact
06Attack Trees — When STRIDE Isn't Enough

Most security defects are predictable. They follow patterns that have repeated for thirty years across thousands of products. Threat modeling is the discipline that finds them before code is written, when the cheapest fix is still possible: a different design.

💡
The four questions of threat modeling
Adam Shostack's framing: (1) What are we building? (2) What can go wrong? (3) What are we going to do about it? (4) Did we do a good job? Every methodology — STRIDE, PASTA, attack trees — is just a way to answer these four questions systematically.

Step 1 — Diagram the System

You cannot threat-model what you cannot see. Start with a data flow diagram (DFD) of just enough fidelity to argue about. Four shapes are usually enough.

User external entity Web App process API process DB TRUST BOUNDARY
A minimal DFD with three trust boundaries. Every red dashed line is a place where data crosses a trust level — and where you must threat-model.

The four shapes:

  • External entity (rectangle) — users, third-party APIs, attackers.
  • Process (circle) — your code: a service, a function, a worker.
  • Data store (parallel lines) — databases, queues, S3, caches.
  • Data flow (arrow) — anything traveling between the above.

And the most important element of all: the trust boundary — a dashed line drawn wherever data crosses from less-trusted to more-trusted (or vice versa). Every trust boundary is a question to answer.

Step 2 — STRIDE, the Threat Catalogue

Microsoft's STRIDE is the most useful enumeration. Six categories, every one mapping to a property of the CIA triad — so you can never write a threat that does not point at something to protect.

S poofing T ampering R epudiation I nfo Disclosure D oS E levation of Privilege STRIDE
STRIDE: six threat classes, one for each desirable property of a system. The wheel turns slowly — review every slice for every component.
ThreatProperty ViolatedWhat it looks likeMitigations
SpoofingAuthenticationPretending to be another user / serviceStrong AuthN, MFA, mTLS, signed JWTs
TamperingIntegrityModifying data in transit or at restHMAC, TLS, signed updates, file integrity monitoring
RepudiationNon-repudiation"It wasn't me" — denying an actionAppend-only audit logs, signed receipts, digital signatures
Information DisclosureConfidentialityLeak of secrets, PII, schema, tokensEncryption, RBAC, masked logs, generic errors
Denial of ServiceAvailabilityCrashing or overwhelming the systemRate limiting, autoscaling, quotas, queue limits
Elevation of PrivilegeAuthorizationGoing from user to admin without permissionRBAC, defense in depth, sandboxing, kernel hardening
Mnemonic — STRIDE
"Some Tampering Repudiates Innocent Defenders' Efforts."
  • Spoofing → Authentication
  • Tampering → Integrity
  • Repudiation → Non-repudiation
  • Information Disclosure → Confidentiality
  • DoS → Availability
  • Elevation of Privilege → Authorization

Step 3 — Run STRIDE on Each Element

The technique is mechanical: for every element in your DFD, walk through every relevant STRIDE category. Not every element is vulnerable to every category. The cheat sheet:

ElementSTRIDE
External entity
Process
Data flow
Data storepartial

Step 4 — Worked Example: A Login Endpoint

📐 Worked example · POST /login
1
Diagram: Browser → API process → Users table. Two trust boundaries (browser/API, API/DB).
2
S — Spoofing: Attacker tries credential stuffing with leaked password lists. Mitigation: per-IP and per-username rate limiting, breach-list checking on password set, MFA.
3
T — Tampering: Attacker modifies the request body in transit. Mitigation: TLS 1.3 enforced; HSTS preload to prevent downgrade.
4
R — Repudiation: User claims they never logged in from a foreign IP. Mitigation: append-only audit log of (timestamp, user, IP, user-agent, result).
5
I — Info Disclosure: The error message distinguishes "unknown user" from "wrong password" — a username oracle. Mitigation: identical message and timing for both cases (constant-time comparison helps).
6
D — DoS: Bcrypt with cost 14 takes ~500 ms; an attacker can hammer /login and starve the workers. Mitigation: rate limit before the password check; consider proof-of-work or CAPTCHA on suspicious traffic.
7
E — EoP: The session cookie issued by /login also carries admin scope from a stale impersonation flag. Mitigation: scope tokens explicitly; never reuse session contexts across roles.

Step 5 — Risk-Rank with DREAD or Likelihood × Impact

Not every threat justifies an immediate fix. DREAD (Damage, Reproducibility, Exploitability, Affected users, Discoverability) once gave a 1–10 score per axis; the modern simplification is just likelihood × impact, on a 5-point scale each, ranked into a heat map.

High likelihood · High impact
  • Credential stuffing on /login
  • Verbose SQL errors leaked to client
  • Public S3 bucket with PII
Lower priority (still tracked)
  • Internal admin tool with weak password (no internet exposure)
  • Rate limiting bypass on a low-cost endpoint
  • Self-XSS that requires the victim to paste into devtools

Attack Trees — When STRIDE Isn't Enough

STRIDE is great for catching known classes. Attack trees are better for thinking like an adversary toward a specific goal. Put the attacker's objective at the root and decompose, AND/OR-style.

Read user emails Compromise account Exploit IDOR on /messages Steal DB backup Phish password Credential stuff Tamper id parameter Public S3 bucket Insider w/ access OR
An attack tree for the goal "read another user's emails." Cheap leaves first — that's where you spend defensive budget.

Attack trees expose cost asymmetries. Phishing is $0.50 per attempt; insider compromise costs months. Defenders waste budget hardening the expensive paths and ignoring the cheap ones. Always cost the leaves.

Active recall
For each STRIDE category, name the corresponding desirable property and one classic mitigation.
Show answer
S → Authentication → MFA. T → Integrity → HMAC / TLS. R → Non-repudiation → signed audit log. I → Confidentiality → encryption + RBAC. D → Availability → rate limiting + autoscaling. E → Authorization → least privilege + sandboxing.

How Often Should You Threat-Model?

The honest answer: continuously, but not exhaustively. The pragmatic schedule for most teams:

  • Per design doc — a threat model section before any new system is approved. 30 minutes is often enough.
  • Per major change — a new trust boundary, a new external integration, a new data class.
  • Annual review — re-run STRIDE on the top-N most critical systems. Threats evolve; so do dependencies.
⚠️
Don't let perfect be the enemy of any
Teams often abandon threat modeling because it feels like a 60-page deliverable. It isn't. A whiteboard DFD plus a STRIDE pass on the top three components, captured in a 1-page doc, is dramatically better than nothing — and is what the best engineering orgs actually do.
🔑
Key takeaways
1) Diagram the system with the four DFD shapes and mark every trust boundary. 2) Walk every element through STRIDE; each category maps to a CIA-style property. 3) Rank threats by likelihood × impact; fix the top of the heat map first. 4) Use attack trees when you need to think like an adversary toward a specific goal — and always cost the leaves.

Finished reading?