Threat Modeling
Structured identification of what can go wrong in a design, before code exists. Answers four questions (Shostack): What are we building? What can go wrong? What are we doing about it? Did we do a good job? This skill is architecture-time analysis — for finding vulns in existing code use loom-security-scan/loom-security-audit; for auth mechanism details use loom-auth.
When
New system design, architecture review, significant feature or trust-boundary change, third-party integration, or compliance evidence. Re-run when the architecture changes — a threat model is a living document, not a one-time deliverable.
Methodologies
STRIDE — the default; apply per element of the DFD
The core technique isn't "brainstorm STRIDE" — it's walking each DFD element and each data flow crossing a trust boundary, asking which STRIDE categories apply to that element.
| Threat |
Violates |
Typical control |
| Spoofing |
Authentication |
Strong authn, mTLS, signed tokens |
| Tampering |
Integrity |
Signatures, HMAC, input validation, WORM logs |
| Repudiation |
Non-repudiation |
Audit logs, signed receipts |
| Information disclosure |
Confidentiality |
Encryption, least-privilege, error hygiene |
| Denial of service |
Availability |
Rate limits, quotas, timeouts, autoscale |
| Elevation of privilege |
Authorization |
AuthZ checks, sandboxing, least privilege |
Element→likely-STRIDE heuristic: external entities → S, R; processes → all six; data flows → T, I, D; data stores → T, I, D (and R if logs).
DREAD — risk scoring (use with caution)
Score Damage, Reproducibility, Exploitability, Affected users, Discoverability (1–10); risk = mean. ⚠ DREAD is widely criticized as subjective and inconsistent across raters (Microsoft dropped it). Prefer a simple Likelihood × Impact matrix, or CVSS for concrete vulns, when you need defensible numbers. Whatever the scale, rank threats to drive mitigation order.
PASTA / LINDDUN
- PASTA — 7-stage, risk-centric, business-objective-driven (objectives → tech scope → decomposition → threat analysis → vuln analysis → attack modeling → risk & mitigation). Use for high-stakes systems needing business alignment.
- LINDDUN — the STRIDE-equivalent for privacy threats (Linkability, Identifiability, Non-repudiation, Detectability, Disclosure, Unawareness, Non-compliance). Reach for it on GDPR/PII-heavy systems.
Process
1. Scope & assets
List assets and why an attacker wants them — this drives everything.
| Asset |
Classification |
Impact if compromised |
| Credentials/secrets |
Confidential |
Account/system takeover |
| Payment data |
PCI-DSS |
Financial + compliance loss |
| PII |
GDPR |
Privacy breach, fines |
2. DFD with trust boundaries (the load-bearing step)
Threats concentrate at trust boundaries — every arrow crossing one is where authn/authz/validation must live. Mark: external entities, processes, data stores, data flows, and boundaries (internet↔DMZ, DMZ↔internal, tenant↔tenant, host↔container, user↔kernel).
[User] --HTTPS--> ║ DMZ ║ [API Gateway] --> ║ Internal ║ [App] --> [DB]
↑ boundary: authn, TLS ↑ boundary: authz, network policy, mTLS
A boundary you didn't draw is a check you won't add. Enumerate every flow: source, destination, protocol, data classification, boundary crossed.
3. Enumerate threats (STRIDE per element)
### API Gateway
| STRIDE | Threat | Likelihood | Impact |
| ------ | ------ | ---------- | ------ |
| S | Forged/`alg:none` JWT | Med | High |
| I | Verbose error leaks stack/version | High | Med |
| D | Rate-limit bypass | Med | High |
| E | BOLA/IDOR → other users' objects | High | Critical |
4. Attack trees (for high-value goals)
Decompose a goal into OR/AND paths; the cheapest leaf is the likely attack and shows where to spend defense.
Steal User Data (goal)
┌──────────┼──────────┐ (OR)
Compromise Exploit App Social
Credentials Vulnerability Engineering
┌───┴───┐ ┌───┴───┐
Phishing Brute SQLi BOLA
[L:H I:H][L:M] [L:M I:C][L:H I:H]
5. Mitigations — track to closure
| Threat | Mitigation | Priority | Status |
| ------ | ---------- | -------- | ------ |
| BOLA/IDOR | Object-level ownership checks (loom-auth) | P0 | Not started |
| SQLi | Parameterized queries | P0 | In progress |
| JWT forgery | Pin alg, validate aud/iss/exp (loom-auth) | P1 | Done |
Every high/critical threat needs a mitigation, an accepted-risk decision (with owner + justification), or a transfer. Silence = unmanaged risk.
High-Signal Threats & Their Real Controls
- BOLA / IDOR (broken object-level authz) — #1 API threat: any object accessed by id must verify caller ownership/tenant, not just "logged in". Details + wrong-vs-right in
loom-auth.
- SSRF — attacker makes your server fetch an internal URL (cloud metadata
169.254.169.254, localhost, internal services). Defense is an allowlist of permitted hosts/schemes — never a blocklist. Blocklists are bypassed by DNS-rebinding, HTTP redirects, IPv6 ([::1]), and decimal/octal/hex-encoded IPs (http://2130706433/). Also disable unused URL schemes and block redirects to non-allowlisted hosts.
- Injection (SQL/NoSQL/command/LDAP/XXE) — parameterize/allowlist; treat every trust-boundary input as hostile.
- Mass assignment — client sets fields it shouldn't (
role, isAdmin, tenant_id); bind explicit allowlists.
- Cloud metadata & IAM escalation — SSRF-to-credentials via the metadata endpoint; enforce IMDSv2, least-privilege roles.
- Supply chain — dependency confusion, typosquat, unsigned artifacts (see
loom-dependency-scan).
Component Quick-Reference
| Component |
Watch for |
| Web app |
XSS, CSRF, clickjacking, open redirect, session fixation |
| API |
Broken authn/authz (BOLA/BFLA), mass assignment, rate-limit bypass, injection |
| Database |
SQLi, privilege escalation, unencrypted data/backups |
| Auth |
Credential stuffing, session fixation, token leakage, MFA bypass |
| File upload |
Malware, path traversal, RCE via content, storage exhaustion |
| Cloud/infra |
Public buckets, IAM escalation, SSRF→metadata, exposed control plane |
| Containers/K8s |
Vulnerable base images, secrets in env/layers, privileged pods, RBAC gaps, container escape |
| 3rd-party/webhooks |
API-key exposure, webhook spoofing (verify HMAC), supply-chain |
| ML systems |
Data poisoning, evasion/adversarial input, model inversion/extraction, PII leakage in outputs |
Threat Model Document Template
# Threat Model: <System> (v1.0, YYYY-MM-DD, author, reviewers)
1. Executive summary — key risks & recommendations
2. System description — purpose, architecture, data classification, trust boundaries
3. Assets — table (asset, classification, owner)
4. Analysis — DFD, STRIDE-per-component, attack trees
5. Risk assessment — table (threat, likelihood×impact or CVSS, level)
6. Mitigations — table (threat, mitigation, owner, timeline, status)
7. Residual risks — accepted risks + justification
8. Review schedule — trigger conditions to revisit
Verification Checklist
1---2name: loom-threat-model3description: Threat modeling methodologies (STRIDE, DREAD, PASTA, attack trees) for secure architecture design.4---56# Threat Modeling78Structured identification of what can go wrong in a *design*, before code exists. Answers four questions (Shostack): **What are we building? What can go wrong? What are we doing about it? Did we do a good job?** This skill is architecture-time analysis — for finding vulns in existing code use `loom-security-scan`/`loom-security-audit`; for auth mechanism details use `loom-auth`.910## When1112New system design, architecture review, significant feature or trust-boundary change, third-party integration, or compliance evidence. Re-run when the architecture changes — a threat model is a living document, not a one-time deliverable.1314## Methodologies1516### STRIDE — the default; apply *per element* of the DFD1718The core technique isn't "brainstorm STRIDE" — it's walking each DFD element and each data flow crossing a trust boundary, asking which STRIDE categories apply to *that* element.1920| Threat | Violates | Typical control |21| ------ | -------- | --------------- |22| **S**poofing | Authentication | Strong authn, mTLS, signed tokens |23| **T**ampering | Integrity | Signatures, HMAC, input validation, WORM logs |24| **R**epudiation | Non-repudiation | Audit logs, signed receipts |25| **I**nformation disclosure | Confidentiality | Encryption, least-privilege, error hygiene |26| **D**enial of service | Availability | Rate limits, quotas, timeouts, autoscale |27| **E**levation of privilege | Authorization | AuthZ checks, sandboxing, least privilege |2829Element→likely-STRIDE heuristic: external entities → S, R; processes → all six; data flows → T, I, D; data stores → T, I, D (and R if logs).3031### DREAD — risk scoring (use with caution)3233Score Damage, Reproducibility, Exploitability, Affected users, Discoverability (1–10); risk = mean. ⚠ DREAD is widely criticized as **subjective and inconsistent** across raters (Microsoft dropped it). Prefer a simple **Likelihood × Impact** matrix, or **CVSS** for concrete vulns, when you need defensible numbers. Whatever the scale, rank threats to drive mitigation order.3435### PASTA / LINDDUN3637- **PASTA** — 7-stage, risk-centric, business-objective-driven (objectives → tech scope → decomposition → threat analysis → vuln analysis → attack modeling → risk & mitigation). Use for high-stakes systems needing business alignment.38- **LINDDUN** — the STRIDE-equivalent for **privacy** threats (Linkability, Identifiability, Non-repudiation, Detectability, Disclosure, Unawareness, Non-compliance). Reach for it on GDPR/PII-heavy systems.3940## Process4142### 1. Scope & assets4344List assets and *why an attacker wants them* — this drives everything.4546| Asset | Classification | Impact if compromised |47| ----- | -------------- | --------------------- |48| Credentials/secrets | Confidential | Account/system takeover |49| Payment data | PCI-DSS | Financial + compliance loss |50| PII | GDPR | Privacy breach, fines |5152### 2. DFD with trust boundaries (the load-bearing step)5354**Threats concentrate at trust boundaries** — every arrow crossing one is where authn/authz/validation must live. Mark: external entities, processes, data stores, data flows, and boundaries (internet↔DMZ, DMZ↔internal, tenant↔tenant, host↔container, user↔kernel).5556```text57[User] --HTTPS--> ║ DMZ ║ [API Gateway] --> ║ Internal ║ [App] --> [DB]58 ↑ boundary: authn, TLS ↑ boundary: authz, network policy, mTLS59```6061A boundary you didn't draw is a check you won't add. Enumerate every flow: source, destination, protocol, data classification, boundary crossed.6263### 3. Enumerate threats (STRIDE per element)6465```markdown66### API Gateway67| STRIDE | Threat | Likelihood | Impact |68| ------ | ------ | ---------- | ------ |69| S | Forged/`alg:none` JWT | Med | High |70| I | Verbose error leaks stack/version | High | Med |71| D | Rate-limit bypass | Med | High |72| E | BOLA/IDOR → other users' objects | High | Critical |73```7475### 4. Attack trees (for high-value goals)7677Decompose a goal into OR/AND paths; the cheapest leaf is the likely attack and shows where to spend defense.7879```text80 Steal User Data (goal)81 ┌──────────┼──────────┐ (OR)82 Compromise Exploit App Social83 Credentials Vulnerability Engineering84 ┌───┴───┐ ┌───┴───┐85 Phishing Brute SQLi BOLA86[L:H I:H][L:M] [L:M I:C][L:H I:H]87```8889### 5. Mitigations — track to closure9091```markdown92| Threat | Mitigation | Priority | Status |93| ------ | ---------- | -------- | ------ |94| BOLA/IDOR | Object-level ownership checks (loom-auth) | P0 | Not started |95| SQLi | Parameterized queries | P0 | In progress |96| JWT forgery | Pin alg, validate aud/iss/exp (loom-auth) | P1 | Done |97```9899Every high/critical threat needs a mitigation, an accepted-risk decision (with owner + justification), or a transfer. Silence = unmanaged risk.100101## High-Signal Threats & Their Real Controls102103- **BOLA / IDOR (broken object-level authz)** — #1 API threat: any object accessed by id must verify caller ownership/tenant, not just "logged in". Details + wrong-vs-right in `loom-auth`.104- **SSRF** — attacker makes your server fetch an internal URL (cloud metadata `169.254.169.254`, `localhost`, internal services). **Defense is an allowlist of permitted hosts/schemes — never a blocklist.** Blocklists are bypassed by DNS-rebinding, HTTP redirects, IPv6 (`[::1]`), and decimal/octal/hex-encoded IPs (`http://2130706433/`). Also disable unused URL schemes and block redirects to non-allowlisted hosts.105- **Injection (SQL/NoSQL/command/LDAP/XXE)** — parameterize/allowlist; treat every trust-boundary input as hostile.106- **Mass assignment** — client sets fields it shouldn't (`role`, `isAdmin`, `tenant_id`); bind explicit allowlists.107- **Cloud metadata & IAM escalation** — SSRF-to-credentials via the metadata endpoint; enforce IMDSv2, least-privilege roles.108- **Supply chain** — dependency confusion, typosquat, unsigned artifacts (see `loom-dependency-scan`).109110## Component Quick-Reference111112| Component | Watch for |113| --------- | --------- |114| Web app | XSS, CSRF, clickjacking, open redirect, session fixation |115| API | Broken authn/authz (BOLA/BFLA), mass assignment, rate-limit bypass, injection |116| Database | SQLi, privilege escalation, unencrypted data/backups |117| Auth | Credential stuffing, session fixation, token leakage, MFA bypass |118| File upload | Malware, path traversal, RCE via content, storage exhaustion |119| Cloud/infra | Public buckets, IAM escalation, SSRF→metadata, exposed control plane |120| Containers/K8s | Vulnerable base images, secrets in env/layers, privileged pods, RBAC gaps, container escape |121| 3rd-party/webhooks | API-key exposure, webhook spoofing (verify HMAC), supply-chain |122| ML systems | Data poisoning, evasion/adversarial input, model inversion/extraction, PII leakage in outputs |123124## Threat Model Document Template125126```markdown127# Threat Model: <System> (v1.0, YYYY-MM-DD, author, reviewers)1281. Executive summary — key risks & recommendations1292. System description — purpose, architecture, data classification, trust boundaries1303. Assets — table (asset, classification, owner)1314. Analysis — DFD, STRIDE-per-component, attack trees1325. Risk assessment — table (threat, likelihood×impact or CVSS, level)1336. Mitigations — table (threat, mitigation, owner, timeline, status)1347. Residual risks — accepted risks + justification1358. Review schedule — trigger conditions to revisit136```137138## Verification Checklist139140- [ ] DFD drawn with **every trust boundary** marked; each boundary-crossing flow enumerated141- [ ] STRIDE applied **per element**, not brainstormed globally142- [ ] Assets tied to attacker motivation and classification143- [ ] Every high/critical threat has a mitigation, accepted-risk, or transfer with an owner144- [ ] BOLA/IDOR checked on every object-addressing endpoint; SSRF defenses are allowlist-based145- [ ] Risk ranking uses a defensible scale (Likelihood×Impact or CVSS, not raw DREAD gut-feel)146- [ ] Model versioned and has a re-review trigger; privacy threats covered (LINDDUN) if PII-heavy