STRIDE is a threat modeling framework that classifies threats into six categories: spoofing, tampering, repudiation, information disclosure, denial of service, and elevation of privilege. Each category names a way a component can be attacked and the security property that attack breaks, so walking the categories over a system diagram produces a threat list instead of a blank page.
That is the whole trick, and it explains why STRIDE outlasted every framework published alongside it. The advice it replaced was "think like an attacker", which is not a method; it is a talent, unevenly distributed, and a process that depends on talent produces results that depend on who was in the room. STRIDE converts the talent into six questions. Ask them of every element and two engineers modeling the same design converge on similar lists, a new hire contributes in their first week, and coverage becomes something you can count rather than something you assert.
Loren Kohnfelder and Praerit Garg proposed it inside Microsoft in 1999, and Adam Shostack's later work there, along with his book Threat Modeling: Designing for Security, turned it into the default vocabulary the rest of the industry borrowed. The age shows in places. The categories were written for a world of desktop software and server processes, so cloud and queue-based patterns need a moment of interpretation, and the categories overlap at the edges in ways that irritate people who want a clean partition. Neither objection has produced a replacement, for a reason worth sitting with: the competition is not a better taxonomy, it is no threat model at all.
The six categories
Each letter pairs a threat class with the property it violates. The examples below are drawn from three system shapes most teams recognize: a web application, a queue-based backend, and cloud infrastructure.
Spoofing (violates authentication)
Someone or something successfully claims an identity that is not theirs.
- The support console decides a request is internal by reading an
X-Forwarded-Forheader, so anyone who can set that header arrives as an internal caller. - Any producer that can reach the broker may publish to the
payments.settledtopic, and the consumer has no way to distinguish your billing service's message from a stranger's. - A role's trust policy lets any principal in a partner's cloud account assume it with no external ID, so a third party (mistaken or malicious) can act as your workload.
The control class is authentication that covers services as well as people: mutual TLS or signed messages between components, scoped trust policies, and a rule that identity is never inferred from a value the caller supplies.
Tampering (violates integrity)
Data or code is modified by someone who should not be able to modify it.
- The order endpoint accepts a
statusfield from the client, so a customer can move their own order torefunded. - Retry logic re-enqueues the message body from the failed attempt rather than a stored copy, so anyone with write access to the queue can change a job's parameters between attempts.
- The build references its base container image by mutable tag, so whoever controls that upstream tag controls what runs in production tomorrow.
The control class is integrity: validate server-side anything a client can set, sign or checksum messages that cross a boundary, pin dependencies by digest, and scope write permissions to the single identity that legitimately needs them.
Repudiation (violates non-repudiation)
An actor performs an action and can plausibly deny it, because nothing recorded it in a form that survives a dispute.
- An administrator changes a customer's plan through a support tool that logs "plan updated" with the service account as the actor, never the human who clicked.
- Jobs are dispatched without a correlation ID, so when a payout runs twice nobody can trace which request produced which attempt.
- Audit logs are written to a bucket the administrator role can also delete from, which means the record of privileged action is editable by the privileged.
The control class is tamper-evident logging: capture the human behind every privileged action, propagate a correlation ID across service hops, and write audit records to append-only storage that the audited identity cannot reach.
Information disclosure (violates confidentiality)
Data reaches a party who was never entitled to it.
- A list endpoint honors a
fieldsparameter literally, so asking forpassword_hashreturns it. - Messages carry the entire customer record because that was convenient at the time, so the analytics consumer receives payment details it has no business holding.
- A database snapshot shared to a second account for a migration is never unshared, and it outlives the migration by two years.
The control class is confidentiality by minimization: allow-list response fields rather than block-list them, put only what the consumer needs on each flow, and scope access to a demonstrated need rather than to network position.
Denial of service (violates availability)
Legitimate users cannot use the system, because someone made it unavailable or too expensive to run.
- A search endpoint accepts an unbounded date range, and one query scans the full table while holding a connection until the pool is drained.
- A fan-out step lets a single inbound event create ten thousand child jobs, so one customer's bulk import starves every other tenant's work for an hour.
- Autoscaling has no ceiling, so a traffic flood becomes a billing event first and an outage second, when the budget guardrail finally stops the service.
The control class is availability engineering: per-tenant quotas and rate limits, bounded queries and bounded fan-out, timeouts and backpressure, and an upper bound on anything that scales itself.
Elevation of privilege (violates authorization)
A user or component gains rights that were never granted to it.
- The admin interface hides the delete-user button from non-admins, and the endpoint behind it checks only that the caller is signed in.
- A worker consumes jobs for every tenant under one database role that can read all of them, so a job whose tenant ID was altered upstream reads across the boundary.
- The CI role can pass a highly privileged deployment role, so anyone able to merge a pipeline change can run a task as an administrator.
The control class is authorization enforced where the decision is made: server-side checks at every entry point, one narrow role per workload, and the recognition that the ability to grant permission is itself a permission worth guarding.
STRIDE-per-element
Asking all six questions of every element wastes the session on combinations that cannot occur, and a session that spends its second half on impossible combinations is a session people stop attending. STRIDE-per-element narrows the analysis by element type: a data flow diagram has only four kinds of thing on it, and each kind attracts a known subset of the letters. This is the form most practitioners actually run, the form encoded in Microsoft's own tooling, and the reason a walk can be finished in an hour rather than abandoned in one.
| Element | S | T | R | I | D | E |
|---|---|---|---|---|---|---|
| External entity | ✓ | ✓ | ||||
| Process | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Data store | ✓ | ✓ | ✓ | ✓ | ||
| Data flow | ✓ | ✓ | ✓ |
The gaps carry the meaning. A data store does not get spoofing because spoofing is a claim about identity, and a store makes no claims: the process in front of it does, which is where the threat belongs. A data flow gets no elevation of privilege for the same reason; a flow has no privileges to elevate, it only carries what the process at each end decided to send. The repudiation column on data stores is the interesting one, because the reason it belongs there is easy to miss. Audit logs are not a separate kind of thing; they are data stores, holding the evidence that an action happened and who performed it. If the store holding that evidence can be altered or deleted, repudiation follows directly: every non-repudiation property the rest of the design relies on quietly evaporates, and the threat lands on the store rather than on the actor.
How to run a STRIDE session
- 1Draw the data flow diagram
External entities, processes, data stores, and the flows between them. Whiteboard fidelity is fine; marketing-architecture fidelity is not. If nobody can draw it, that is the finding.
- 2Mark trust boundaries
Every line where data crosses from one level of trust to another: the internet edge, a tenant boundary, a call to a vendor, the jump from application code to infrastructure permissions. Threats cluster on these lines.
- 3Walk each element with its letters
Take elements one at a time and ask only the categories that apply to that type. Finishing every element beats going deep on the first two and running out of hour.
- 4Record threats and map controls
For each threat, name the control that answers it and whether that control exists today, is planned, or is absent. An unanswered threat is the output, not a failure of the session.
- 5Count what is unmitigated
The number of threats with no control, by severity, is the one metric a threat model owes the rest of the program. It is what goes to the risk register and what tells you when to re-model.
Two practical rules do most of the work. Timebox the session to ninety minutes and end on time even if elements remain; an unfinished walk you resume next week beats a three-hour meeting nobody schedules again. Appoint one scribe who does nothing else, because the failure mode of a lively session is a great conversation and four legible words on a whiteboard. Everyone else argues; the scribe writes.
The second rule is about phrasing. Write every threat as a full sentence with an actor and an asset: not "SQL injection" or "spoofing on the API", but "an unauthenticated internet caller submits crafted input to the search endpoint and reads other tenants' orders". Fragments feel efficient in the room and are unusable a month later, when the person triaging them cannot tell what was meant. The sentence form also exposes threats that were never real: if you cannot name a plausible actor, you have written a worry rather than a threat. If ninety minutes of everyone's calendar is the part that will not survive contact with your organization, the same walk can be run asynchronously against a diff, and either way it belongs inside the wider security design review rather than standing alone as an event.
The template
The artifact a session produces is a table, and six columns are enough. Element and STRIDE category say where the threat was found and which question found it, which is what makes coverage checkable later. Threat is the full sentence. Mitigating control names what answers it. Owner and status are the two columns teams leave off and then regret, because a threat with no owner is a note and a threat with no status cannot be counted. Here is what three rows look like for a login service.
| Element | STRIDE category | Threat | Mitigating control | Owner | Status |
|---|---|---|---|---|---|
| Login endpoint (process) | Spoofing | An attacker replays credentials from an unrelated breach against the endpoint at scale and takes over the accounts that reused a password. | Credential-stuffing protection: breached-password screening at sign-in, per-IP and per-account throttling, step-up verification on anomalous sign-ins. | Identity team | Planned, Q4 |
| Session token store (data store) | Information disclosure | An operator with read access to the cache reads live session tokens and resumes any signed-in user's session. | Store only a hash of the session token, scope cache access to the auth service role, alert on human reads. | Platform | Open |
| Password reset handler (process) | Elevation of privilege | A user requests a reset for an address they do not control, and the flow issues a token that is valid before ownership is verified. | Bind the reset token to the verified address, expire it in fifteen minutes, invalidate all sessions on completion. | Identity team | Mitigated |
A spreadsheet in this shape is a perfectly good place to start, and it works until the questions get harder: which systems have been modeled since the architecture changed, how many threats are unmitigated right now, which control in the catalog answers this threat and does it exist anywhere else. Those questions are about relationships between things, and relationships are what spreadsheets stop holding. That is the gap our threat modeling tool is built for: threat models that live with the architecture rather than beside it, with threats anchored to diagram elements and mapped to the controls, risks, and evidence they belong to.
Where STRIDE stops
STRIDE is a security taxonomy, and it is honest about being only that. It finds nothing in a system that lawfully collects personal data and then uses it in ways the people it describes never anticipated, because nothing there is broken: privacy needs its own categories, which is what LINDDUN supplies. It also has no opinion about which threat matters most. A spoofing threat on an internal dashboard and one on your payment flow read identically on the page until someone adds business context, which is the lens PASTA brings and the reason many teams borrow its opening stages for intake. We compare all three in STRIDE vs PASTA vs LINDDUN.
The overlap between categories deserves a plain answer, because it is the objection raised most often and it matters least. A successful tampering attack frequently is an elevation of privilege, and a spoofed identity often produces information disclosure. Purists read that as a taxonomy defect. In practice it is a feature of a discovery tool: arriving at the same threat down two different paths is redundancy, not error, and redundancy is exactly what you want from something whose job is to leave nothing unexamined. Record the threat once, under whichever letter found it first, and move on.
Systems containing models stretch it in a third direction. The six categories still hold, but the example questions underneath them have to change: tampering now includes poisoning a retrieval corpus, information disclosure includes the context window as an exfiltration channel, and elevation of privilege includes reaching a tool's permissions through the model. We work through that question set in threat modeling AI systems.
Start with the diagram, walk the letters, write full sentences, count what is unmitigated. Run that on everything you design and you will find more than a deeper methodology run on the two systems that made it onto someone's calendar.