To threat model a REST API, draw the client, the API, the database and any third party, mark where trust changes, then apply STRIDE to each data flow and store. A small API can be covered in an hour and will usually produce five to ten tickets. Here is a worked example.
The system
A notes service. A mobile app and a web app call an API over HTTPS. The API authenticates users with tokens, stores notes in a database, and sends a webhook to a third party when a note is shared.
Step 1: Draw it
Following the OWASP guidance, show external entities, processes, data stores, data flows and trust boundaries:
- External entities: user's app, third party webhook receiver.
- Process: the API.
- Data store: the notes database.
- Flows: app to API, API to database, API to third party.
- Trust boundaries: between the internet and the API, between the API and the database, and between your system and the third party.
OWASP defines a trust boundary as the place where the trust level changes. Every flow that crosses one deserves attention.
Step 2: Apply STRIDE to each flow
App to API (crosses the internet boundary)
- Spoofing: can someone present a stolen or forged token? Check token lifetime and signing.
- Tampering: can a request body change a field the user should not control, such as an owner id?
- Repudiation: do we log who changed or deleted a note?
- Information disclosure: does a note id in the URL let a user fetch someone else's note?
- Denial of service: is there rate limiting on login and search?
- Elevation of privilege: can a normal user call an admin endpoint?
API to database
- Tampering: is the query built with parameters, or strings?
- Information disclosure: does the database account have read access to more than it needs?
- Elevation of privilege: does the API run with an administrator database role?
API to third party webhook
- Spoofing: can the receiver tell the message came from you? Sign the payload.
- Information disclosure: does the payload contain more note data than needed?
- Denial of service: if the receiver is slow, does the API block?
Step 3: Rate and choose responses
Use High, Medium and Low for likelihood and impact, as OWASP suggests, and consider the fix effort. In this example:
- Missing object level authorisation on note ids: High. Fix first.
- Over broad database role: Medium, with a cheap fix.
- No logging of deletes: Medium.
- Webhook payload not signed: Medium.
For each, pick mitigate, eliminate, transfer or accept, and name an owner.
Step 4: Write tickets
Each ticket names the flow, the threat, the fix and a test. Example: "Check on every note read that the caller owns or has been granted the note. Add a test that user B cannot read user A's note."
Step 5: Review
Ask whether the diagram matches production, whether any flow was skipped, and whether each fix can be tested. OWASP lists a wrong diagram as a pitfall.
What the example shows
Most of the findings are not exotic. They are missing checks at boundaries. The value of the session is finding them before an attacker does.
Keep it current
Add a line to your pull request template for changes to endpoints or data flows: does the threat model need an update? OWASP says a model should be maintained as the system changes.
Quick check
Is a third party part of the model?
Yes. Mark it as an external entity, with a trust boundary on the flow. You cannot control it, so decide what you send and how you verify it.
How many findings should we expect?
It varies. If a session finds none, check whether the diagram or the prompts were too shallow.
Sources
Last reviewed: 19 October 2026.