Threat modeling with STRIDE — a worked example.
We pick a tiny web app and walk it through STRIDE, then write the prompt that gets an LLM to do 60% of the same work as a reviewer.
Threat modeling sounds heavy. In practice the useful version of it is a one-hour exercise with a whiteboard and the STRIDE acronym. We will do it for a deliberately small app, then show how to extract the same work from an LLM at scale.
The system: a paste service
Users paste text, get back a URL with a random ID, share the URL. Pastes optionally expire. There are no accounts. The architecture is four boxes:
[ Browser ] →https→ [ Web ] →TCP→ [ DB ]
↓
[ Cache ]
STRIDE in one paragraph each
STRIDE walks each component and asks six questions. The acronym is your prompt: every box on the diagram, every arrow, gets each letter applied to it.
| Letter | Threat category | CIA property attacked |
|---|---|---|
| S | Spoofing | Authenticity (a form of Integrity) |
| T | Tampering | Integrity |
| R | Repudiation | Non-repudiation |
| I | Information Disclosure | Confidentiality |
| D | Denial of Service | Availability |
| E | Elevation of Privilege | Authorization |
Walking the diagram
Browser → Web (the arrow)
- S: TLS server cert prevents impersonation. Mitigated by HTTPS.
- T: in-flight tampering. Mitigated by TLS AEAD.
- I: an eavesdropper on the wire. Mitigated by TLS.
- D: floods, slowloris. Mitigated by CDN / rate limit.
Web (the application)
- S: there are no logins, so spoofing of identity is N/A. But the paste ID itself is an identifier — guessable IDs let an attacker "impersonate" any paste. Open question: is the ID random enough?
- T: can a user POST to a URL that lets them overwrite someone else's paste? Open question.
- R: can the operator prove which IP submitted a malicious paste? Logs and retention policy needed.
- I: paste IDs in URLs end up in browser history, Referer headers, logs of intermediate proxies. Open question: do we leak paste content via Referer?
- D: unbounded paste size = disk fill. Open question: what is the max body size?
- E: the admin endpoint — does it exist, is it on the same port, is it authenticated?
Web → DB and Web → Cache
- T / I: are these connections TLS or plaintext on the local network? On a flat VPC, plaintext is fine if the segment is locked down; on a shared network, it is not.
- D: cache eviction on memory pressure may cause cascading DB load.
- E: SQL injection on user-provided text. Open question: prepared statements only?
Not a stack of "vulnerabilities". A short list of open questions that someone in the room cannot answer with confidence — and a plan to close each one. Threats you can already mitigate are noted but not interesting.
Concrete mitigations for our open questions
- Paste ID randomness: 128 bits of entropy from
secrets.token_urlsafe(22). Reject any shorter ID at the router. - Overwrite via POST: ID issuance is the only place a paste is created; the route accepts no
idfrom the client. - Referer leak: set
Referrer-Policy: no-referreron paste view pages. - Body size: cap at 1 MB at the proxy. Return 413 above.
- SQL injection: parameterised queries enforced by the ORM; a CI rule fails the build if a raw SQL string mentions
%s.
The LLM prompt that gets you 60% there
Threat modeling is mechanical enough that a well-prompted LLM can do most of it. The prompt below has been refined over a dozen real reviews. Plug your own architecture into the placeholder.
You are a security reviewer. I will give you an architecture description. Walk it with STRIDE. For every component and every data flow, output: - Component or flow name - One line per STRIDE letter, marked one of: MITIGATED (and by what) OPEN (and what to investigate) N/A (and why) - Do NOT speculate about implementation details that are not in the description. - At the end, list the OPEN items as a numbered to-do. Architecture: <paste your diagram description here>
Two things matter about that prompt. It forces a per-component table (which an LLM is good at) and it forbids speculation (which an LLM is bad at). The output is a starting point, not a final report — you walk it with the team and turn each OPEN into a "we know" or "we need to fix".
What you have just learned
Threat modeling is not a meeting where you list everything that could go wrong. It is a structured way of finding the things nobody at the table can confidently answer. STRIDE is the cheapest structure that catches most of them. An LLM can scaffold the first draft for you and let you spend the meeting on the answers.