The security mindset and threat modelling
Learn how security people think and use four questions plus STRIDE to find what can go wrong in your own app before attackers do.
Most security bugs are not clever hacks. They are ordinary mistakes: a check that was forgotten, a secret left in a file, input that was trusted when it should not have been. Security is the habit of asking "how could this be misused?" while you build, not after you ship.
This lesson gives you the vocabulary, the mindset and a simple method called threat modelling that you can use on any app. We will use the Brew & Bean pickup-order app as the example. Everything in this track is defensive: you practise on your own apps and on labs built to be attacked.
The vocabulary
Words you will see everywhere
| Term | Meaning | Brew & Bean example |
|---|---|---|
| Asset | Something worth protecting | Customer phone numbers, order history, the admin login |
| Threat | Something bad that could happen | Someone reads another customer's order |
| Vulnerability | A weakness that allows a threat | GET /orders/{id} returns any order without checking who is asking |
| Attacker | Anyone who tries to misuse the system | A curious customer, a bot, a former employee |
| Risk | How likely and how damaging a threat is | Likely and moderately damaging, so fix soon |
| Control | A measure that reduces risk | Check that the order belongs to the logged-in user |
Notice that risk is about likelihood times impact. A bug that is easy to exploit and exposes phone numbers matters more than a bug that needs rare conditions and exposes nothing important. You cannot fix everything first, so you rank.
The CIA triad
Security goals are often grouped into three ideas. They are called the CIA triad (nothing to do with the agency).
Confidentiality: only the right people can read the data. Integrity: data cannot be changed in ways it should not be. Availability: the system works when people need it.
For Brew & Bean: a leaked phone number breaks confidentiality. A customer changing the price of their own order breaks integrity. A flood of fake orders that stops real customers from ordering breaks availability. When you review a feature, ask which of the three it could hurt.
Think like a builder who is also a sceptic
The security mindset has a few habits.
Never trust input. Anything that comes from outside your server is untrusted: form fields, URL parameters, headers, cookies, uploaded files, even data from your own frontend. The browser is under the user's control, so a hidden field or a disabled button is a suggestion, not a rule.
Assume failure. Passwords will leak somewhere, one layer will be bypassed, a developer will make a mistake. Design so that one failure does not become a disaster. This is called defence in depth: several independent layers.
Least privilege. Give every user, service and key only the access it needs. The database account used by the website does not need permission to drop tables.
Keep it simple. Every feature, endpoint and dependency is more attack surface. Features you do not need are risk with no benefit.
Secure by default. The safe option should be what happens when nobody configures anything.
A common beginner trap
Hiding is not securing. Putting an admin page at an unguessable URL is not access control. If the only protection is that nobody knows the address, it is not protected. This is called security by obscurity.
Threat modelling in four questions
Threat modelling sounds formal, but the core is four questions you can ask on a whiteboard in 30 minutes. They come from well-known threat-modelling guidance such as OWASP's.
1. What are we building? 2. What can go wrong? 3. What are we going to do about it? 4. Did we do a good enough job?
The method
- 1Draw the system. Boxes for the browser, the API, the database and any third party (a payment or SMS service). Draw arrows for the data that moves between them. Mark trust boundaries: lines where data crosses from a less trusted zone to a more trusted one, such as the internet to your API.
- 2List assets. What data and abilities matter? For Brew & Bean: customer name and phone, order status, the ability to change a status to
picked_up, admin access. - 3Find threats at each arrow and boundary. Use the STRIDE prompts below to avoid forgetting categories.
- 4Rate and rank. For each threat, note how likely and how bad. High-high first.
- 5Choose a response. Fix it, reduce it, accept it knowingly, or avoid it by removing the feature. Write the decision down.
- 6Turn the result into work. Create tickets and tests. A threat model that nobody acts on is just a document.
STRIDE: a checklist for what can go wrong
STRIDE is a memory aid from Microsoft with six categories of threat. Walk through each one for each part of your diagram.
STRIDE applied to the coffee shop
| Letter | Threat | Property broken | Brew & Bean question |
|---|---|---|---|
| S | Spoofing (pretending to be someone else) | Authentication | Can I place an order as another phone number? Can I log in as admin? |
| T | Tampering (changing data) | Integrity | Can I send my own total in POST /orders? |
| R | Repudiation (denying an action) | Accountability | If a status was changed to cancelled, do we know who did it? |
| I | Information disclosure | Confidentiality | Do error messages or GET /orders/{id} reveal other people's data? |
| D | Denial of service | Availability | Can one client create thousands of orders per minute? |
| E | Elevation of privilege | Authorisation | Can a customer call PATCH /orders/{id}/status, which only staff should use? |
A worked example
Take one feature: a customer places an order with POST /orders. The request travels from the customer's phone browser, over the internet, to the FastAPI server, which writes to the database. The trust boundary is between the browser and the API.
Walking through STRIDE gives a short table of findings.
Threat model for POST /orders
| Threat | Likelihood | Impact | Response |
|---|---|---|---|
Client sends a fake total (Tampering) | High, easy to do | Medium, shop loses money | Server computes total from the menu; ignore any client value |
| Anyone reads any order by guessing ids (Info disclosure) | High | Medium, phone numbers leak | Check ownership on every read; use hard-to-guess ids |
Customer changes status to picked_up (Elevation) | Medium | Medium | Only staff role can call the status endpoint |
Bot floods POST /orders (Denial of service) | Medium | High, real orders blocked | Rate limit per IP and per phone |
| No record of who cancelled an order (Repudiation) | Medium | Low | Log user id and time for every status change |
Four of these five have the same root cause: trusting what the client says. The fixes are covered in this track: *Authorisation and broken access control*, *Injection attacks* and *Securing APIs*.
Where to apply it and how often
Do a short threat model when you design a feature, change how data flows, add a third-party service or handle new sensitive data. Do it again when the design changes. Small and frequent beats big and rare.
Threat modelling is also the cheapest security work. Fixing a design problem on a whiteboard costs minutes. Fixing it after launch can cost weeks and your users' trust.
Act as a security reviewer helping me threat model a feature. Use the STRIDE categories.
Feature: [describe the feature, e.g. customers log in and view their past orders].
Tech: [e.g. React frontend, FastAPI backend, Postgres, hosted on Render].
Data handled: [e.g. name, phone, order history].
For each STRIDE category give up to two realistic threats, how likely and how serious each is (low/medium/high), and one concrete defensive control. Output a table. Only defensive advice, no exploit instructions.What to expect: Check each threat against your real design. AI will list generic threats, so delete the ones that do not apply and add ones it missed. Treat the output as a prompt for discussion, not a finished model.
How this comes up in interviews
Interviewers rarely ask you to recite STRIDE. They ask "how would you secure this feature?" or "what could go wrong with a login page?" A strong answer names the assets, walks through who could attack and how, and gives layered controls. Saying "I would first ask what we are protecting and from whom" signals maturity. Also be ready for: the CIA triad, defence in depth, least privilege, and the difference between authentication (who are you) and authorisation (what may you do).
Try it: Threat model your own project
Pick a project you built or one from this platform (for example the Brew & Bean ordering site). Draw its boxes and arrows on paper. Mark trust boundaries. List three assets. Apply STRIDE to the single most important arrow and write at least one threat per letter. Rank them and pick the top two to fix.
After a threat-modelling session
- I know what my assets are.
- I know where my trust boundaries are.
- I asked the STRIDE questions for each data flow.
- Every high risk has an owner and a ticket.
- I wrote down risks I chose to accept.
Key takeaways
- Security means protecting confidentiality, integrity and availability.
- Risk is likelihood times impact: rank threats instead of fixing at random.
- Never trust input from outside your server, including your own frontend.
- Defence in depth and least privilege limit the damage when something fails.
- Threat model with four questions and STRIDE, and turn findings into tickets and tests.
- Security by obscurity is not protection.
Check yourself
Finishing the quiz marks the lesson as done.
1. A customer edits the total field in a request to pay less. Which security property is broken?
2. What is a trust boundary?
3. Why is hiding the admin page at a secret URL not real protection?
4. In STRIDE, a former employee's still-active login being used is mostly which threat?
5. What does 'least privilege' mean for the website's database account?
Saved on this device. Create a free account to keep it on every device.
Practise this with Sam
A real mock interview, out loud, with an honest scorecard. Free to start.