Most serious vulnerabilities originate at design time, not coding. A lightweight threat model done early, with a clear owner, is worth more than a 100-page pentest report after go-live.
What is a threat model?
Threat modeling is the process of answering Adam Shostack's four questions:
- What are we working on? — Draw a data flow diagram (DFD).
- What can go wrong? — Apply STRIDE to enumerate threats.
- What are we going to do about it? — Mitigation or accepted risk with a clear owner.
- Did we do a good job? — Review after implementation.
STRIDE in one minute
| Threat | Property violated | Example |
|---|---|---|
| Spoofing | Authentication | Identity impersonation, token reuse |
| Tampering | Integrity | Modifying requests or DB rows |
| Repudiation | Non-repudiation | No audit trail to prove an action |
| Information disclosure | Confidentiality | PII or keys leaking through logs |
| Denial of service | Availability | Brute force, slowloris, expensive queries |
| Elevation of privilege | Authorization | IDOR, sandbox escape, container break-out |
Drawing a DFD at the right level
Four element types belong on a DFD:
- External entity: user, third-party API.
- Process: service, function.
- Data store: DB, S3, queue.
- Data flow: arrow between elements.
The most important concept is the trust boundary: the line between zones of differing trust (Internet ↔ web tier, app ↔ DB, tenant A ↔ tenant B). Every arrow that crosses a trust boundary needs authentication, validation and encryption.
Start at DFD level 1 (one service plus immediate dependencies). Avoid generic level 0 or going as deep as level 3 — it costs time without changing decisions.
Apply STRIDE to each element
A practical trick: for each element on the DFD, ask the six STRIDE questions. You don't need a threat in every cell — skip when it makes no sense. Capture in a table:
| Element | Threat | Description | Mitigation | Owner | Severity |
| -------------- | ------ | ------------------------------------------ | ---------------------- | ----- | -------- |
| Login endpoint | S | Credential brute force | Rate limit + MFA | @team | High |
| Login endpoint | I | User enumeration via error message | Generic error message | @team | Medium |
| Upload service | T | File replace race on object storage | Versioning + checksum | @team | Medium |
| Order DB | E | IDOR on /orders/{id} | Owner-scoped authz | @team | High |
Scoring risk
- CVSS v3.1/v4: industry standard, ideal for concrete vulnerabilities, with a sharable vector string.
- OWASP Risk Rating: simple (Likelihood × Impact), easy to explain to non-technical stakeholders.
Pick one method and document it. Don't let each team invent its own — comparison becomes impossible.
The risk register is a living asset
- Each risk has an owner.
- Each risk has a mitigation deadline or a recorded reason for accepting it.
- Reviewed each quarter and after major architecture changes.
- Linked to the issue tracker so mitigations are real tickets.
When to use LINDDUN or PASTA
- LINDDUN when the service handles a lot of PII/PHI and you need privacy-focused threat modeling.
- PASTA when threats need tight alignment with business risk via a formal 7-stage process — fits critical systems (banking, healthcare).
Conclusion
Threat modeling is not magic. A 60-minute session with a level-1 DFD, a STRIDE checklist and a risk register is enough to keep a service free of common design flaws. Repeat it on a cadence, give it owners, link it to ADRs — that is how threat modeling becomes a habit instead of a yearly event.
