STRIDE Threat Model DFD

A STRIDE threat model starts from a data flow diagram (DFD) of the system, draws trust boundaries where privilege changes, and then walks every element asking which of six threats applies: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service and Elevation of privilege. This sample models a small online shop and tags each element with numbered threats and mitigations. DFDs are not UML: UML covers software structure and behaviour; DFDs and the other diagrams in this section are the standard notations used alongside it.


1. The Diagram

Online Shop: Level-1 DFD with Trust Boundaries and STRIDE Threats TB1: Internet | DMZ TB2: Internal network Customer browser / mobile app 1.0 Web App public API 2.0 Auth Service 3.0 Order Service Users DB D1 Orders DB D2 Payment provider HTTPS req response session check order user row order row charge (mTLS) T1 T2 T3 T4 T5 T6 # Element STRIDE threat Mitigation T1 Customer (entity) Spoofing: credential stuffing MFA, rate limits, breached-password check T2 HTTPS req (flow) Tampering / Info disclosure: MITM TLS 1.3 only, HSTS, certificate pinning in app T3 1.0 Web App Elevation of privilege: IDOR object-level authorization on every request T4 3.0 Order Service Repudiation: "I never ordered that" append-only, signed audit log with user id T5 D1 Users DB Information disclosure: DB dump encryption at rest, Argon2id hashes, least privilege T6 1.0 Web App at TB1 Denial of service: request flood WAF + rate limiting, autoscaling, CDN

Walk through it in this order:

  1. The Customer is an external entity on the Internet side of TB1. Anything that crosses TB1 is untrusted input.
  2. 1.0 Web App receives HTTPS requests. It sits in the DMZ and is the most exposed process, so it collects three threats (T3, T6 and the flow threat T2).
  3. Inside TB2 the web app calls 2.0 Auth Service to check the session and 3.0 Order Service to place orders.
  4. Each service owns one data store: D1 Users DB and D2 Orders DB. No process reads another service's store directly.
  5. The order service charges the card through the external Payment provider over mutual TLS. That flow crosses TB2 outward, so it is another boundary to analyse.
  6. The table at the bottom records each threat with the element it applies to and the agreed mitigation. Every row becomes a ticket or a test.

2. How to Read It

DFD + Threat-Model Notation Entity external entity Process process (code) Store data store data name data flow trust boundary T1 numbered threat Threats cluster where flows cross a trust boundary: start the analysis there.

The notation is Gane-Sarson/DeMarco-style DFD as used by the Microsoft Threat Modeling Tool and OWASP Threat Dragon: rectangles are things you do not control, circles are your code, open rectangles hold data at rest, and arrows carry named data. The dashed yellow lines are what makes it a threat model rather than a plain DFD.

3. Variant: STRIDE-per-Element Matrix

STRIDE-per-Element: Which Threats Apply to Which DFD Element S Spoofing T Tampering R Repudiation I Info disclosure D Denial of service E Elevation External entity yes - yes - - - Process yes yes yes yes yes yes Data store - yes yes* yes yes - Data flow - yes - yes yes - * a data store faces repudiation threats when it holds audit or log data

Instead of brainstorming, many teams use this matrix as a checklist: for each element on the DFD, consider only the threats marked for its type. A process can suffer all six; a data flow can only be tampered with, read or blocked. A real model of the shop above produces roughly 4 x 6 + 3 x 4 + 7 x 3 candidate threats, which is why boundary-crossing elements are triaged first.

4. Pros, Cons, and When to Use

Pros

Cons

When to use

When not to use

5. Diagrams-as-Code

OWASP Threat Dragon stores models as JSON; for docs, a Mermaid flowchart with subgraphs as trust boundaries is close enough:

flowchart LR
    C[Customer]
    subgraph TB1 [DMZ]
        W((1.0 Web App))
    end
    subgraph TB2 [Internal network]
        A((2.0 Auth Service))
        O((3.0 Order Service))
        D1[(D1 Users DB)]
        D2[(D2 Orders DB)]
    end
    P[Payment provider]
    C -- HTTPS req --> W
    W -- response --> C
    W -- session check --> A
    W -- order --> O
    A -- user row --> D1
    O -- order row --> D2
    O -- "charge (mTLS)" --> P