STRIDE — One Structured Method
Six prompts — spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege — applied to each element of a diagram, which converts "think of what could go wrong" into a finite, checkable list.
Frame the problem
Security starts with a concrete asset, attacker capability and trust crossing.
The six prompts and what each violates
STRIDE's value is that it is a *finite* list of question types, so a review can be complete in a way that free-form brainstorming cannot. Each letter maps to a security property, and asking the question is asking whether that property can be violated at this point in the system.
Run it per element — per data flow, per process, per data store, per external entity — and specifically at boundary crossings. Six questions times eight elements is forty-eight prompts, most answered in seconds, and the handful that produce an uncomfortable pause are the findings.
It is one method among several and not a complete one. STRIDE is oriented toward technical threats against components; it has little to say about business-logic abuse (a legitimate sequence of legitimate operations producing an illegitimate outcome), about privacy harms from data you are entitled to hold, or about supply-chain and organisational threats. Use it as scaffolding, and supplement it with Attack Trees for goal-directed reasoning and with the abuse-case thinking in API Security as a Boundary.
| Letter | Question | Violates | Example finding |
|---|---|---|---|
| Spoofing | Can someone pretend to be another identity? | Authenticity | Webhook accepts any POST to /webhooks/psp without verifying the signature |
| Tampering | Can someone modify data or code they should not? | Integrity | Order total is read from a client-supplied field rather than recomputed server-side |
| Repudiation | Can someone deny an action with no contrary evidence? | Accountability | Refunds are issued with no audit entry naming the operator |
| Information disclosure | Can someone read data they should not? | Confidentiality | Error response includes the full SQL statement and column names |
| Denial of service | Can someone stop legitimate users? | Availability | Unbounded page size lets one request scan the whole table |
| Elevation of privilege | Can someone gain capabilities not granted? | Authorization | The role field is accepted from the request body on profile update |
Applying it without producing noise
The failure mode of STRIDE is a spreadsheet with three hundred rows, most of which say "not applicable", and a team that never does it again. Three constraints keep it useful.
Apply it at boundaries, not everywhere. A data flow entirely inside one process across a trusted call does not need six prompts. The flow from the browser to the API, from the API to the payment provider, from the queue to the worker — those are where the six questions earn their time.
Answer with a mechanism or a gap, never with a label. "Mitigated by authentication" is not an answer to a spoofing question about a webhook; "verified by HMAC over the raw body with a per-endpoint secret, timestamp checked within five minutes" is. If the answer cannot name the mechanism, the finding is that nobody knows whether the mechanism exists.
Prioritise by blast radius as you go, not afterwards. A tampering threat against a display preference and a tampering threat against an order total are both "T", and treating them equally is how the list becomes unreadable. Mark each finding with the asset it touches and sort at the end.
FLOW: Browser ──POST /orders──► Order API (crosses: internet → app)
S Can the caller be someone else? → session cookie, HttpOnly+Secure+SameSite=Lax OK
T Can the payload be altered? → TLS in transit; BUT total is taken from body FINDING (high)
R Can the actor deny it later? → audit row {actor, order, ts, ip, result} OK
I What leaks back? → 404 vs 403 distinguishes existence FINDING (low)
D Can one caller exhaust us? → rate limit 60/min/user; body capped 256 kB OK
E Can the caller gain privilege? → 'role' and 'discount' accepted from body FINDING (critical)
DECISIONS
total → recompute server-side from catalogue prices owner: payments this sprint
role → explicit allow-list of updatable fields owner: accounts today
404/403 → accept; enumeration risk is low for order ids owner: security review in Q3Key points
- STRIDE gives completeness, not insight: it stops you forgetting a category, and the thinking is still yours.
- Apply it per element at trust boundary crossings, not to every arrow in the diagram.
- Answer each prompt with a named mechanism or an admitted gap — never with a label like "authentication".
- It is weak on business-logic abuse, privacy and supply chain; pair it with attack trees and abuse cases.
- Tag each finding with the asset it touches so the list can be prioritised by blast radius rather than by letter.
Boundary control exercise
This lesson uses the shared boundary-control exercise.
Follow the attack
Safe conceptual simulation: capability → missing control → crossed boundary → asset impact.
- 1Attacker → the category nobody asked about: usually repudiation (no audit trail) or elevation via a mass-assignment field.
- 2Category gap → capability: the missing question corresponds exactly to the missing control.
- 3Capability → asset: proceed as in the specific vulnerability lesson for that category.
- A missing category is a systematic blind spot rather than a single bug: no audit trail means every future incident is unscopeable.
- Uneven application produces a false sense of coverage, which is worse than knowing you have not looked.
Defend, detect, recover
One prevention is a single point of security failure. Layer it and make failure observable.
- • Keep a per-element STRIDE checklist in the design template so the six questions are asked by default.
- • Require a named mechanism for every "mitigated" answer, and treat unnamed mitigations as findings.
- • Re-run the pass on the flows that changed, not the whole model, so the cost stays proportional.
- • Audit whether each claimed mitigation has a corresponding test; claimed-but-untested is the common decay path.
- • Compare the model's answers against production behaviour periodically — signatures verified, limits enforced, audit rows present.
- • When an incident occurs, identify which STRIDE category it was and check whether that category was answered for every similar element.
- • Fix the class across all elements rather than only where it was exploited.
- • STRIDE finds categories of technical threat, not business-logic abuse where every individual step is authorized.
- • A complete STRIDE pass on a wrong diagram produces confident, complete, wrong results.
- • The method says nothing about likelihood, so prioritisation must come from elsewhere.