Threat modeling is the structured process of identifying potential threats to a system and designing mitigations before attackers find them. It’s one of the most valuable security practices that’s almost universally underused — especially in small and medium-sized organizations. This guide teaches you the fundamentals using the STRIDE methodology with practical examples.
Why Threat Model?
The goal of threat modeling is to answer four questions:
- What are we building?
- What can go wrong?
- What are we going to do about it?
- Did we do a good enough job?
Without threat modeling, security decisions are reactive — you fix problems after they’re exploited. Threat modeling makes security proactive.
STRIDE: The Threat Categories
Microsoft’s STRIDE framework categorizes threats into six types:
# STRIDE Threat Categories:
S - Spoofing Identity → Impersonating a user or system component
T - Tampering with Data → Modifying data in transit or at rest
R - Repudiation → Denying an action occurred (no audit trail)
I - Information Disclosure → Exposing data to unauthorized parties
D - Denial of Service → Disrupting availability
E - Elevation of Privilege → Gaining unauthorized permissions
Step-by-Step Threat Modeling Process
Step 1: Draw the Data Flow Diagram (DFD)
# Simple web application DFD:
# Components:
[User Browser] --> [Load Balancer] --> [Web Server] --> [App Server] --> [Database]
--> [Cache (Redis)]
--> [File Storage (S3)]
# Data flows to document:
# 1. User login (POST /api/auth) - username + password
# 2. API requests (GET/POST /api/data) - with JWT token
# 3. File uploads (POST /api/upload) - binary data
# 4. Database queries (SQL) - sensitive customer data
# 5. Admin access (GET /admin) - privileged operations
# Mark trust boundaries:
# Internet / DMZ boundary (between user and load balancer)
# DMZ / Internal network boundary (between LB and app servers)
# App server / Database boundary (internal, privileged)
Step 2: Apply STRIDE to Each Component
# Example: Analyze the Authentication API endpoint
# SPOOFING threats:
# - Attacker submits another user's credentials
# Mitigation: Strong password policy + MFA + account lockout
# TAMPERING threats:
# - JWT token modified to elevate privileges
# Mitigation: Sign JWTs with strong secret, verify signature on every request
# - SQL injection to modify database
# Mitigation: Parameterized queries
# REPUDIATION threats:
# - User denies making a request ("I didn't do that!")
# Mitigation: Audit logs with timestamp, user ID, IP, action
# INFORMATION DISCLOSURE threats:
# - Password exposed in logs
# Mitigation: Never log passwords, mask sensitive fields
# - Error messages reveal database structure
# Mitigation: Generic error messages in production
# DENIAL OF SERVICE threats:
# - Brute force login attempts
# Mitigation: Rate limiting, CAPTCHA, account lockout
# - Large file uploads consuming server resources
# Mitigation: File size limits, async processing
# ELEVATION OF PRIVILEGE threats:
# - Regular user accessing admin endpoints
# Mitigation: RBAC authorization check on EVERY endpoint
Step 3: Prioritize with DREAD Scoring
# DREAD scores each threat 1-10:
# D - Damage: How bad is the breach?
# R - Reproducibility: How easily can it be repeated?
# E - Exploitability: How much skill/effort to exploit?
# A - Affected users: How many users impacted?
# D - Discoverability: How easily can attackers find this?
# Example scoring — JWT not validated on admin endpoint:
# Damage: 10 (attacker becomes admin)
# Reproducibility: 9 (trivial to repeat)
# Exploitability: 9 (just modify JWT payload, no signature check)
# Affected users: 10 (all users' data accessible)
# Discoverability: 7 (tools like Burp Suite find this automatically)
# DREAD Score: (10+9+9+10+7)/5 = 9.0 — CRITICAL, fix immediately
# Example scoring — verbose error messages:
# Damage: 3 (helps attacker but not directly exploitable)
# Reproducibility: 9 (always reproducible)
# Exploitability: 8 (just trigger an error)
# Affected users: 2 (one attacker at a time)
# Discoverability: 7 (scanners find these)
# DREAD Score: (3+9+8+2+7)/5 = 5.8 — Medium, fix in next sprint
Free Threat Modeling Tools
# Microsoft Threat Modeling Tool (free):
# Download: microsoft.com/en-us/securityengineering/sdl/threatmodeling
# - Creates DFDs visually
# - Automatically generates STRIDE threats for each component
# - Generates reports
# OWASP Threat Dragon (open source):
# Install: npm install -g threat-dragon
# threat-dragon # Launches in browser
# - Web-based DFD editor
# - Export to JSON/PDF
# - GitHub integration
# pytm (Python threat modeling library):
pip install pytm
# Example pytm script:
from pytm import TM, Server, Datastore, Dataflow, Boundary, Actor
tm = TM("My Web App")
internet = Boundary("Internet")
dmz = Boundary("DMZ")
user = Actor("User", inBoundary=internet)
webapp = Server("Web App", inBoundary=dmz, isHardened=True)
db = Datastore("Database")
user_to_app = Dataflow(user, webapp, "HTTP Request", protocol="HTTPS")
app_to_db = Dataflow(webapp, db, "SQL Query", protocol="SQL")
tm.process() # Generates threat report
When to Threat Model
- New application design — before a single line of code is written
- Architecture changes — adding new components or integrations
- Annually — review and update existing threat models
- After incidents — add new threats discovered through breaches
Wrap Up
Threat modeling doesn’t require expensive consultants or weeks of time. A one-hour whiteboard session using STRIDE can identify dozens of security risks in a new feature before code is written. Build it into your development process and you’ll catch the kinds of vulnerabilities that would otherwise make headlines.