Skip to content

STRIDE threat modelling

QuickBite is adding online ordering. Customers choose food, pay, and wait for the restaurant to confirm the order.

The happy path is clear. A customer submits an order, the kitchen receives it, and the app sends updates.

Security asks a different question: what could go wrong before we build it?

That question is called threat modelling. You look at a design, imagine ways it could be misused, then decide what the code needs to prevent.

Threat modelling happens before the bug report

Code review looks at code that already exists.

Threat modelling looks at the feature while it's still cheap to change.

The STRIDE list

STRIDE is a memory aid for six ways an attacker might mess with a system. The letters stand for:

LetterThreatPlain question
SSpoofingCan someone pretend to be someone else?
TTamperingCan someone change data they should not change?
RRepudiationCan someone deny doing something because no record exists?
IInformation disclosureCan someone see data they should not see?
DDenial of serviceCan someone stop the app from working for others?
EElevation of privilegeCan someone do more than their role allows?

The course phrase is useful: STRIDE gives you six ways an attacker might mess with your system.

Let's point those six questions at QuickBite.

JunoThe STRIDE list STRIDE is a checklist for your imagination. It keeps you from asking only the first security question that comes to mind.

The letters are less scary once you turn them into plain questions: can someone pretend, change, deny, read, block, or do more than they should?

JunoThe STRIDE list Use STRIDE to stop the review from depending on whoever happens to be in the room. Six prompts, same order, every feature.

The useful output isn't the acronym. It's the row you can turn into work: server checks who owns the order before showing it, payment amount is calculated server-side, order changes are logged with account and time.

JunoThe STRIDE list STRIDE came out of Microsoft threat-modelling work in the late 1990s, which is a nice reminder that the durable part was not the tooling. It was the repeatable prompt list.

The letters aren't a guarantee. They miss abuse where a user does exactly what their role allows at a harmful scale, and they don't decide whether you should have collected the data in the first place.

Treat STRIDE as a disciplined first pass, not a certificate from the security gods. The gods are unavailable and the build is due Friday.

Walk QuickBite with STRIDE

Start with one feature flow:

  1. Customer creates an order.
  2. Server calculates the total.
  3. Customer pays.
  4. Restaurant accepts or rejects the order.
  5. Customer receives updates.

Now ask the six STRIDE questions against the flow.

ThreatQuickBite exampleDecision
SpoofingA request claims to be another customer.Use the signed-in session, not a user id from the body.
TamperingThe browser sends a cheaper price.Calculate price on the server from menu data.
RepudiationA restaurant says it never rejected an order.Log who changed the order status and when.
Information disclosureOne customer reads another customer's order.Check ownership before returning order details.
Denial of serviceOne user sends thousands of orders.Add rate limits and request size limits.
Elevation of privilegeA customer calls a restaurant-only endpoint.Check role and restaurant membership on the server.

That table is already useful. It tells the team which checks need to exist before the feature is safe enough to ship.

A threat model only matters when each threat turns into a decision.

JunoWalk QuickBite with STRIDE Pick one feature and walk it like a story. At each step, ask what someone could pretend, change, deny, read, block, or do without permission.

Then write the decision beside it. A worry becomes useful when someone can build or test the answer.

JunoWalk QuickBite with STRIDE The table is the artifact. Keep it close to the ticket, not buried in a separate document nobody opens after planning.

Phrase rows as acceptance criteria where you can. Server calculates the total from menu data is buildable. Price tampering is possible is a note someone agrees with and then forgets.

JunoWalk QuickBite with STRIDE The quiet failure mode is writing threats with no owner. Every row should end as one of three things: fix now, accept with a reason, or defer with a named follow-up.

That sounds bureaucratic until the incident review asks why the order total trusted the browser. A dated accepted risk is a decision. An empty decision column is archaeology with worse lighting.

Potential threat modelling

Potential threat modelling starts wide. Instead of one feature, you look across a whole system or a large part of it.

For QuickBite, that might mean:

  • everything a customer can do after signing in
  • everything a restaurant owner can do
  • the whole payment path
  • every place order data leaves the app

This style is useful when you inherit an app, launch a new system, or want to find old design problems.

The risk is scope creep. "The whole app" turns into a long meeting and a tired room. Pick a boundary people can point at.

Scope it before you start

Potential threat modelling needs a fixed scope and a fixed amount of time.

Without both, the exercise expands until everyone stops making decisions.

JunoPotential threat modelling Potential threat modelling is the wide version. You look at a whole area, such as the payment path, and ask what could go wrong there.

Keep the edge small enough to see. "The payment path" is useful. "The whole app" usually turns into a fog machine.

JunoPotential threat modelling Use potential threat modelling when the system shape matters more than one feature. Customer actions, restaurant-owner actions, payment, uploads and admin tools are good scopes.

Before the meeting starts, write the boundary. If a threat falls outside it, park it. Otherwise the session becomes a tour of every worrying thing in the product.

JunoPotential threat modelling The wide sweep rarely produces sprint-sized work. It produces shape problems: a payment flow with too many callers, an admin surface that shares the customer session, a webhook path nobody owns.

That's still valuable, but aim the output at planning. Rank the findings by what they cost to leave alone, and write the argument clearly enough that someone can fund it later without reconstructing the meeting from memory. Memory is where risk decisions go to become folklore.

Try it

QuickBite adds a feature: a customer can leave a review on a completed order, and the restaurant can reply.

Walk it with STRIDE. For each letter, name one thing that could go wrong and the check that answers it.

Compare your answers
LetterWhat could go wrongThe check
S SpoofingSomeone posts a review as another customerThe server takes the author from the session, never from the request body
T TamperingA restaurant edits a review's text or rating after the factOnly the author may edit their own review, and replies are separate records
R RepudiationA restaurant denies posting an abusive replyLog who wrote what and when, with the account id
I Information disclosureA review exposes the customer's full name or addressDecide what's public before storing it, and return only those fields
D Denial of serviceSomeone posts thousands of reviews, or one review a megabyte longA length limit on the text and a rate limit on the endpoint
E Elevation of privilegeA customer replies as if they were the restaurantThe reply route checks the account owns that restaurant

Two worth noticing. R is the one people skip, because nothing is broken until somebody disputes what happened, and by then the record either exists or it doesn't.

And S has a single fix that closes it everywhere: take identity from the session, never from a field the caller sent. A review carrying its own authorId is a review anyone can sign with anybody's name.

Where this goes next

STRIDE gives you the six questions. The next chapter changes the scale.

Instead of sweeping a whole system, feature-based threat modelling puts those questions onto one feature at a time. That's the version most developers can use inside normal planning.