In the previous lesson we positioned design as the highest-return phase of the S-SDLC, with threat modeling as its flagship activity. We foreshadowed this back in lesson 03-05 (Insecure Design), where we said that an architectural flaw cannot be fixed with a patch and that the way to anticipate it had a name of its own, whose treatment we deferred until here. The time has come. Threat modeling is the structured exercise of imagining, before building, how an adversary would try to abuse the system, so you can decide which defenses to build in by design. It is the discipline that answers the question a pentest only answers late and expensively: what could go wrong? In this lesson we build a complete threat model of the BazarNube checkout.
Contents
- What threat modeling is and when to do it
- Shostack's four questions
- Data flow diagrams (DFD) and trust boundaries
- STRIDE: a language of threat categories
- Risk prioritization (DREAD and alternatives)
- Tools: Threat Dragon and pytm
- A threat model of the BazarNube checkout
- Common mistakes and tips
- Exercises
- Conclusion
What threat modeling is and when to do it
Threat modeling means analyzing a design to systematically look for its weak points and the appropriate countermeasures. It does not require the system to be built: it is done on diagrams and decisions, which is precisely its advantage. It is a team exercise, not a report an expert writes alone; the value lies as much in the resulting document as in the conversation that produces it.
When should you do it?
- When designing a new feature that involves sensitive data or money.
- When facing a significant architectural change (a new service, a new external integration, a new data store).
- Periodically for critical components, because the system and the threats evolve.
- It is not realistic to model every commit: reserve it for what matters, guided by the data classification you did in the requirements phase.
Shostack's four questions
Adam Shostack popularized a four-question framework that structures any modeling session. OWASP adopts it as the backbone of the process.
| # | Question | What it produces |
|---|---|---|
| 1 | What are we building? | A DFD with its trust boundaries |
| 2 | What can go wrong? | A list of threats (using STRIDE) |
| 3 | What are we going to do about it? | Mitigations and controls |
| 4 | Did we do a good job? | Verification and review |
The fourth question closes the loop: a threat model is not a dead artifact, it is revisited when the design changes. Note the parallel with the S-SDLC: question 3 feeds ASVS requirements and question 4 leans on verification (for example, ZAP checking that a mitigation works).
Data flow diagrams (DFD) and trust boundaries
To answer "what are we building?" you draw a Data Flow Diagram (DFD). A DFD uses a deliberately small vocabulary:
- External entity (rectangle): an actor outside our control (a user, a payment gateway).
- Process (circle): code that transforms data (an API, a service).
- Data store (two parallel lines): a database, cache, or queue.
- Data flow (arrow): the movement of data between the above.
- Trust boundary (dashed line): the frontier where the level of trust changes; crossing it is where most threats are born.
Trust boundaries are the key concept. Every time a piece of data crosses one—from the Internet to our API, from our API to the database, from our backend to a third-party service—there is an opportunity for the attacker and a need to validate, authenticate, or encrypt. Modeling well consists, in large part, of focusing attention on those crossings.
STRIDE: a language of threat categories
Answering "what can go wrong?" by hand leads to omissions. STRIDE, created at Microsoft, is a mnemonic that forces you to consider six threat categories for each element of the DFD. Each category is the negation of a desirable security property.
| Letter | Threat | Property violated | Example | Related Top Ten risk |
|---|---|---|---|---|
| S | Spoofing | Authentication | Impersonating another user | A07 Identification and Authentication Failures |
| T | Tampering | Integrity | Altering the price in the request | A08 Integrity Failures; A03 Injection |
| R | Repudiation | Non-repudiation | Denying having placed an order | A09 Logging and Monitoring Failures |
| I | Information disclosure | Confidentiality | Seeing someone else's card data | A01 Access Control; A02 Cryptographic Failures |
| D | Denial of service | Availability | Saturating the checkout | A05 Security Misconfiguration (limits) |
| E | Elevation of privilege | Authorization | A regular user acting as admin | A01 Broken Access Control |
A practical technique is STRIDE-per-element: walk through each process, store, and flow of the DFD and ask which STRIDE letters apply. Not all of them apply to every element, and that is fine; the value is the systematic coverage.
Risk prioritization (DREAD and alternatives)
Not all threats deserve the same attention. You need to prioritize so you invest effort where it matters. DREAD is a classic model that scores each threat on five axes (typically 1-3 or 1-10):
- Damage — potential damage.
- Reproducibility — how easy the attack is to reproduce.
- Exploitability — the effort required to exploit it.
- Affected users — how many users it affects.
- Discoverability — how easy the vulnerability is to discover.
You add up the axes and sort. DREAD is simple but subjective (two people score differently), so many teams prefer alternatives:
| Method | Advantage | Drawback |
|---|---|---|
| DREAD | Fast, intuitive | Subjective, poorly reproducible |
| Likelihood x impact matrix | Aligned with general risk management | Requires calibrating scales |
| CVSS | Industry standard | Designed for vulnerabilities, not design threats |
| OWASP Risk Rating | Tailored to web apps, clear factors | More steps |
For BazarNube we will use a simple likelihood x impact matrix (High/Medium/Low), enough to prioritize and easy to agree on as a team.
Tools: Threat Dragon and pytm
Modeling can be done on a whiteboard, but there are tools that help keep the model alive and versioned:
- OWASP Threat Dragon: a graphical application (web and desktop) for drawing DFDs and annotating STRIDE threats. It saves the model as JSON, versionable in Git alongside the code. Ideal for teams that prefer the visual approach.
- pytm: a threat modeling as code framework in Python. You describe the system as objects (processes, stores, flows, boundaries) in a script and the tool generates the DFD and a threat report. It fits the "everything as code" philosophy we will see in DevSecOps.
# Minimal sketch with pytm: the system is described as code
from pytm import TM, Server, Datastore, Actor, Boundary, Dataflow
tm = TM("BazarNube Checkout")
internet = Boundary("Internet")
internal = Boundary("Internal network")
customer = Actor("Customer"); customer.inBoundary = internet
api = Server("Checkout API (Node/Express)"); api.inBoundary = internal
db = Datastore("PostgreSQL Orders"); db.inBoundary = internal
payment = Dataflow(customer, api, "Send payment data (HTTPS)")
save = Dataflow(api, db, "Save order")
tm.process() # generates DFD and threat reportThe tool does not replace judgment: it is the team that decides which threats are real and which mitigations apply.
A threat model of the BazarNube checkout
Let's apply the four questions to BazarNube's most sensitive flow: the checkout, where personal data, addresses, and payment converge.
Question 1: What are we building? (DFD)
graph LR
Customer[Customer React browser]
API[Checkout API Node/Express]
Legacy[Pricing service Java/Spring]
DB[(PostgreSQL Orders)]
Gateway[External payment gateway]
Customer -->|1 order data HTTPS| API
API -->|2 price lookup| Legacy
API -->|3 save order| DB
API -->|4 tokenize and charge| Gateway
Gateway -->|5 confirmation webhook| API
subgraph TB_Internet [Trust boundary: Internet]
Customer
end
subgraph TB_Internal [Trust boundary: Internal network]
API
Legacy
DB
end
subgraph TB_ThirdParty [Trust boundary: Third party]
Gateway
end
The trust boundary crossings are: customer→API (Internet to internal), API→gateway, and the gateway→API webhook (internal to third party). That is where we concentrate the analysis.
Questions 2 and 3: What can go wrong and what do we do? (STRIDE + mitigations)
| Element / flow | STRIDE | Concrete threat | Likelihood x Impact | Mitigation | OWASP control |
|---|---|---|---|---|---|
| Customer → API | T | Tampering with the price in the order JSON | High x High | The price is recomputed on the server from the catalog; the client's value is never trusted | A04 Design; ASVS V5 (validation) |
| Customer → API | S | Using another customer's session/token | Medium x High | Robust session tokens, rotation, MFA for sensitive changes | A07; ASVS V2, V3 |
| API (process) | E | A regular user forces another's order (IDOR) | High x High | Per-object authorization: the order is bound to the authenticated user | A01; ASVS V4 |
| API → DB | I | Order data leak through injection | Medium x High | Parameterized queries; least privilege for the DB user | A03; ASVS V5 |
| API ↔ Gateway | I | Exposure of card data | Low x Very high | Do not store the PAN; tokenization at the gateway; TLS | A02; ASVS V6, V9 |
| Gateway → API webhook | S/T | Forged webhook confirming a nonexistent payment | Medium x High | Verify the webhook's HMAC signature; validate the amount against the order | A08; ASVS V10 |
| Checkout (flow) | D | Abuse of the endpoint to exhaust stock or overload it | Medium x Medium | Rate limiting, concurrency control over stock | A05; ASVS V11 |
| API (process) | R | A customer denies having placed an order | Low x Medium | Tamper-proof, timestamped logging of every transaction | A09; ASVS V7 |
Notice how each mitigation links to a control we have already studied: the threat model does not invent new defenses, it decides which ones from the Top Ten/ASVS catalog apply to this design. The threat model translates generic risks into concrete, verifiable requirements. That is exactly the bridge to the testing phase, where ZAP and manual tests will confirm that the mitigation works.
Question 4: Did we do a good job?
The team's Security Champion reviews the model, the mitigations are recorded as acceptance requirements (ASVS) in the backlog, and the model is flagged for review when the gateway changes or when, for example, deferred payment is added. The forged-webhook threat becomes a story with its corresponding test.
Common Mistakes and Tips
- Modeling the perfect system, not the real one. The DFD must reflect how it truly works, including the shortcuts and the legacy Java service. An idealized model hides the real threats.
- Chasing absolute exhaustiveness. It is impossible to enumerate every threat. Prioritize the trust boundary crossings and the sensitive data; a "good enough" model that gets reviewed beats a perfect one that never gets finished.
- Turning it into a dead document. If the model is not revisited when the design changes, it expires. Tie it to the process (question 4) and keep it versioned alongside the code.
- Doing it alone. The value is in the conversation between development, security, and product. Without the team, the knowledge of the real system is lost.
- Tip: start small. A one-hour whiteboard DFD of the most critical flow contributes more than a theoretical course. The skill is developed by modeling.
Exercises
Exercise 1. In the checkout DFD, a developer proposes that the frontend send the already-computed total price "to save a query." Identify the STRIDE category of the risk and the correct mitigation.
Exercise 2. Classify each threat with the appropriate STRIDE letter: (a) an attacker replays a captured payment webhook, (b) a user changes the order_id in the URL and views someone else's order, (c) the log does not record who canceled an order.
Exercise 3. BazarNube is going to add "sign in with Google." Picture the new flow mentally and point out one new trust boundary and one STRIDE threat that appears with this integration.
Solutions
Solution 1. It is Tampering (integrity manipulation): trusting a price sent by the client lets it be altered in transit or from the browser to buy for less. The mitigation is to never trust client data for money decisions: the server recomputes the price from the authorized catalog. It relates to A04 (Insecure Design) and ASVS V5 (validation).
Solution 2.
- (a) Tampering and/or Spoofing (a replayed/forged webhook); mitigated with an HMAC signature and anti-replay control (nonce/timestamp).
- (b) Elevation of privilege / broken access control (IDOR); per-object authorization.
- (c) Repudiation; tamper-proof logging with identity and timestamp.
Solution 3. A new trust boundary appears with the external identity provider (Google) and the OAuth/OIDC flow that crosses to a third party. A typical threat is Spoofing: accepting an identity token that is not properly validated (signature, audience, issuer, expiration) would allow impersonating a user. It is mitigated by validating the token per the OIDC standard and binding the local account securely. It relates to A07 and ASVS V2/V3.
Conclusion
Threat modeling is the practice that gives substance to the design phase of the S-SDLC: with a DFD and its trust boundaries we answer "what are we building," with STRIDE "what can go wrong," with mitigations linked to the Top Ten and ASVS "what do we do," and with the review "did we do a good job." At BazarNube we have turned a checkout flow into a prioritized list of verifiable requirements. But a good design only holds up if the rest of the process respects it automatically and continuously. In the next lesson, 07-03, we take these mitigations into the realm of automation: how DevSecOps turns these controls into checks the pipeline runs on every change.
OWASP Course: Guidelines and Standards for Web Application Security
Module 1: Introduction to OWASP
Module 2: Main OWASP Projects
- OWASP Top Ten
- OWASP ASVS (Application Security Verification Standard)
- OWASP SAMM (Software Assurance Maturity Model)
- OWASP ZAP (Zed Attack Proxy)
- Other Key Projects: WSTG, Cheat Sheets and Dependency-Check
Module 3: OWASP Top Ten 2021 in Depth
- A01:2021 – Broken Access Control
- A02:2021 – Cryptographic Failures and Sensitive Data Exposure
- A03:2021 – Injection
- Cross-Site Scripting (XSS) in Depth
- A04:2021 – Insecure Design
- A05:2021 – Security Misconfiguration
- XML External Entities (XXE)
- A06:2021 – Vulnerable and Outdated Components
- A07:2021 – Identification and Authentication Failures
- A08:2021 – Software and Data Integrity Failures (Insecure Deserialization)
- A09:2021 – Security Logging and Monitoring Failures
- A10:2021 – Server-Side Request Forgery (SSRF)
Module 4: OWASP ASVS (Application Security Verification Standard)
Module 5: OWASP SAMM (Software Assurance Maturity Model)
Module 6: OWASP ZAP (Zed Attack Proxy)
- Introduction to ZAP
- Installation and Configuration
- Vulnerability Scanning
- Automating Security Testing
Module 7: Best Practices and Recommendations
- Secure Software Development Life Cycle (SDLC)
- Threat Modeling
- Integrating Security into DevOps (DevSecOps)
- Security Training and Awareness
- Additional Tools and Resources
Module 8: Practical Exercises and Case Studies
- Exercise 1: Identifying Vulnerabilities
- Exercise 2: Implementing Security Controls
- Case Study 1: Analyzing a Security Incident
- Case Study 2: Improving the Security of a Web Application
