Skip to content
Breachfolio
Hero illustration for: Threat modeling with STRIDE – a worked example.
LEVEL 3 CYBERSECURITY

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.

15 min read Daniel A. & Óscar S.

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.

LetterThreat categoryCIA property attacked
SSpoofingAuthenticity (a form of Integrity)
TTamperingIntegrity
RRepudiationNon-repudiation
IInformation DisclosureConfidentiality
DDenial of ServiceAvailability
EElevation of PrivilegeAuthorization

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?
The output of a threat-modeling session

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

  1. Paste ID randomness: 128 bits of entropy from secrets.token_urlsafe(22). Reject any shorter ID at the router.
  2. Overwrite via POST: ID issuance is the only place a paste is created; the route accepts no id from the client.
  3. Referer leak: set Referrer-Policy: no-referrer on paste view pages.
  4. Body size: cap at 1 MB at the proxy. Return 413 above.
  5. SQL injection: parameterised queries enforced by the ORM; a CI rule fails the build if a raw SQL string mentions %s.

STRIDE generalises: a second pass, on a mobile login flow

Doing the framework once on a paste service risks making it look web-app-specific. It isn't. STRIDE is six questions you ask of any diagram with boxes and arrows, and a mobile app's login flow is a genuinely different shape of system: an API instead of server-rendered pages, an OS-level secure keystore instead of cookies, a third-party OTP vendor in the loop. Same six letters, different nouns.

[ Mobile App ] →https→ [ Auth API ] → [ Session store ]
                             ↓
                     [ SMS/Push OTP provider ]

Rather than repeat the full per-component walk, here is the same exercise condensed into the table shape a reviewer (or an LLM, as below) would actually produce – one standout question per component instead of all six letters:

Component / flowStandout letterOpen question
App → Auth APISpoofingIs the connection pinned to a known certificate, or does the app trust any CA-issued cert – including one from a compromised or coerced CA?
Auth APIElevation of PrivilegeAre login attempts rate-limited per-account as well as per-IP? Per-IP alone doesn't stop distributed credential stuffing.
Auth API → OTP providerInformation DisclosureDoes the OTP vendor log phone number and code together in a way a compromised third party could replay?
Session storeTamperingAre session tokens signed (HMAC or equivalent), so a client can't forge an elevated claim like a different account ID?
App (local storage)Information DisclosureIs the token in OS-level secure storage (Keychain / Keystore), or sitting in plaintext SharedPreferences a rooted device can read?

Notice the questions are structurally identical to the paste-service ones – only the nouns changed, from "paste ID" to "session token," from "Referer leak" to "insecure local storage." That is the actual value of STRIDE: it doesn't require domain expertise in mobile security or web security specifically, only discipline in applying the same six letters to whatever is on the diagram in front of you.

Concrete mitigations for the mobile flow

  1. Certificate pinning: pin the API's certificate, or its public key, inside the app so a mis-issued certificate from any trusted CA can't intercept the connection – and plan for the operational cost of rotating pins when certs renew.
  2. Per-account rate limiting: throttle failed logins by account identifier as well as source IP, with exponential backoff, so credential stuffing spread across thousands of residential IPs still hits a wall.
  3. Separate OTP logging: never write the phone number and the one-time code to the same log line or record. If support tooling needs both, require a separate, access-controlled lookup to join them.
  4. Signed session tokens: use a signed format – a JWT with a server-held key, or an opaque token validated server-side – so a modified client can't silently promote its own claimed privileges.
  5. OS-level secure storage: store the token in the Android Keystore or iOS Keychain, never in SharedPreferences or UserDefaults, and mark it non-exportable where the platform supports it.

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.

Prompt template
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.

STRIDE isn't the only option

The framework most often mentioned in the same breath as STRIDE is DREAD: but DREAD isn't a competing way to find threats, it's a scoring rubric for ranking the ones STRIDE already found (Damage, Reproducibility, Exploitability, Affected users, Discoverability). The two are commonly used together: STRIDE generates the list, DREAD helps decide what to fix first. The frameworks that actually compete with STRIDE for finding threats in the first place are heavier tools like PASTA and, for narrower questions, attack trees.

FrameworkApproachBest forTrade-off
STRIDESix threat categories applied to every component and data flow on a diagramFast, structured design reviews – an hour, not a weekDoesn't rank threats by business risk on its own
PASTASeven-stage, risk-centric process tying business objectives to simulated attacksLarger systems where you must justify prioritisation to non-security stakeholdersMuch heavier – days of work, not an hour with a whiteboard
Attack treesOne root goal (e.g. "steal customer PII") decomposed into AND/OR branches of how an attacker gets thereModeling one specific high-value target in depthDoesn't systematically cover a whole system the way STRIDE's component walk does

These aren't mutually exclusive. A common pattern is STRIDE as the default for every design review that touches a data flow diagram, with PASTA or an attack tree reserved for the small number of crown-jewel systems – payment processing, the auth service itself – that justify the extra rigor. An attack tree even makes a natural follow-up to a STRIDE finding: once STRIDE flags "elevation of privilege on the auth API" as an open question, an attack tree rooted at "attacker gains admin session" forces you to enumerate every branch that gets there – credential stuffing, a leaked signing key, a vulnerable dependency – rather than stopping at the first plausible path. Start with STRIDE. Reach for the others when STRIDE's output tells you a specific asset needs a deeper look.

Frequently asked questions

What does STRIDE stand for in threat modeling?
STRIDE stands for Spoofing (authenticity), Tampering (integrity), Repudiation (non-repudiation), Information Disclosure (confidentiality), Denial of Service (availability), and Elevation of Privilege (authorization). Each letter is applied to every component and every arrow on an architecture diagram.
How do you apply STRIDE to a real system?
Walk every component and every data flow on the architecture diagram and ask each of the six STRIDE questions against it, marking each one MITIGATED (and by what), OPEN (and what to investigate), or N/A (and why). For example, on a paste-sharing service, the STRIDE walk surfaces open questions like whether paste IDs are random enough, whether body size is capped, and whether SQL queries are parameterized.
What is the actual output of a threat modeling session?
Not a stack of vulnerabilities: a short list of open questions that nobody in the room can confidently answer, plus a plan to close each one. Threats that are already mitigated are noted but aren't the interesting part of the exercise.
Can an LLM help with threat modeling?
Yes: a well-prompted LLM can do roughly 60% of a STRIDE review by producing a per-component table marking each STRIDE letter as MITIGATED, OPEN, or N/A, while being explicitly told not to speculate about implementation details not in the description. The output is a starting draft the team still needs to walk through and resolve, not a final report.
Who writes this

Daniel A. and Óscar S. run Breachfolio, a small independent site about security and AI. This article was drafted with AI assistance and reviewed by a person before it went live. We write from documentation, vendor sources and published research rather than from original lab benchmarks, and we link a source in the sentence that relies on it. How we work · About us

Previous
Cryptography you can actually use.
End of section
Browse all articles