Post

Week 4 — Day 23: Threat Modeling with STRIDE

A full walkthrough of threat modeling using STRIDE — drawing data flow diagrams, identifying threats, rating risk, and applying the methodology to a real cloud-native application.

Week 4 — Day 23: Threat Modeling with STRIDE

What is Threat Modeling?

Threat modeling is structured thinking about what can go wrong in a system — done before you build, not after a breach.

Instead of waiting for a pentest or a real attack to discover vulnerabilities, you proactively ask:

  • What are we building?
  • What can go wrong?
  • What are we going to do about it?
  • Did we do a good enough job?

The output is a prioritized list of threats and the controls needed to address them.

When to do it: During design, when adding significant new features, when the attack surface changes (new API endpoint, new data type, new user type).


STRIDE Threat Categories

STRIDE is a threat classification model developed by Microsoft. Each letter maps to a category of threat:

LetterThreatViolatesExample
SSpoofingAuthenticationAttacker forges JWT token to impersonate another user
TTamperingIntegrityAttacker modifies a request in transit to change an order amount
RRepudiationNon-repudiationUser denies making a transaction, logs don’t prove otherwise
IInformation DisclosureConfidentialityAPI returns full user object including password hash
DDenial of ServiceAvailabilityAttacker floods the API causing it to become unresponsive
EElevation of PrivilegeAuthorizationRegular user accesses admin endpoints by modifying their JWT role claim

Step 1 — Draw a Data Flow Diagram (DFD)

A DFD maps how data moves through your system. It uses four elements:

SymbolMeaning
RectangleExternal entity (user, external service)
Circle / rounded boxProcess (your application component)
Two parallel linesData store (database, S3 bucket, cache)
ArrowData flow (HTTP request, DB query, message)
Dashed boxTrust boundary (crossing this boundary = higher scrutiny)

Example — MindCraft application DFD:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[User Browser]
     |
     | HTTPS request
     ▼
  ─ ─ ─ ─ ─ ─ ─ (Trust Boundary: Internet → AWS) ─ ─ ─ ─ ─
     |
     ▼
[CloudFront + WAF]
     |
     | Filtered request
     ▼
[ALB]
     |
     ▼
  ─ ─ ─ ─ ─ ─ (Trust Boundary: Public → Private subnet) ─ ─
     |
     ▼
[API Service (ECS)]  ──────────────── [Redis Cache]
     |                                     (Data Store)
     | SQL query
     ▼
[RDS PostgreSQL]    ←── [S3 Bucket (file uploads)]
  (Data Store)               (Data Store)
     |
     ▼
[CloudTrail / CloudWatch]
  (Data Store — audit logs)

[SCREENSHOT]A hand-drawn or tool-drawn DFD on paper or in draw.io/Miro showing the MindCraft application components, data flows, and trust boundaries clearly labeled

Tools for drawing DFDs:

  • Draw.io (free, web-based)
  • Microsoft Threat Modeling Tool (free, Windows)
  • OWASP Threat Dragon (open source)
  • Miro or Lucidchart (collaborative)

Step 2 — Apply STRIDE to Each Element

For every data flow, process, and data store — ask which STRIDE threats apply.

Applying STRIDE to the MindCraft App

Data Flow: User → CloudFront

ThreatQuestionFinding
S SpoofingCan a user forge another user’s identity?JWT tokens — are they validated server-side?
T TamperingCan a request be modified in transit?HTTPS enforced? HTTP redirected?
R RepudiationCan users deny their actions?Are user actions logged with identity?
I Info DisclosureDoes the response leak sensitive data?API error messages — do they expose stack traces?
D DoSCan this flow be flooded?WAF rate limiting in place?
E ElevationCan a user access resources they shouldn’t?Authorization checks on every API endpoint?

Process: API Service (ECS)

ThreatFindingControl
S SpoofingService calls other internal services — are they authenticated?mTLS or IAM auth between services
T TamperingCan environment variables or config be modified by an attacker?Read-only filesystem, no SSRF to metadata service
R RepudiationAre all business operations logged with user ID and timestamp?Structured logging with user context
I Info DisclosureDoes the service log sensitive data (passwords, PII)?Log scrubbing for PII
D DoSCan a single user’s request trigger expensive DB queries?Query timeouts, rate limiting per user
E ElevationCan a regular user call admin endpoints?RBAC enforced, roles validated server-side

Data Store: RDS PostgreSQL

ThreatFindingControl
S SpoofingWho can connect to the DB?Only app tier SG, IAM DB auth
T TamperingCan data be modified outside the application?No direct internet access, audit logging
R RepudiationAre DB writes auditable?RDS audit logs enabled
I Info DisclosureIs data encrypted at rest and in transit?RDS encryption, SSL connections enforced
D DoSCan the DB be overwhelmed?Connection pooling, RDS instance sizing
E ElevationCan the app user perform DDL operations?App DB user has DML only (SELECT/INSERT/UPDATE/DELETE)

Step 3 — Rate Each Threat (DREAD)

After identifying threats, prioritize them using DREAD scoring:

FactorScore 1-3Meaning
D Damage3 = Critical data loss or full compromise 
R Reproducibility3 = Reproducible every time 
E Exploitability3 = No skill required, tools available 
A Affected users3 = All users affected 
D Discoverability3 = Publicly known, easy to find 

Example rating — JWT token not validated server-side:

FactorScoreReason
Damage3Full account takeover
Reproducibility3Consistent exploit
Exploitability2Requires JWT knowledge
Affected users3Every user
Discoverability2Requires probing
Total13/15Critical

Example rating — verbose error messages in API:

FactorScoreReason
Damage1Info disclosure only
Reproducibility3Always present
Exploitability1Just read the response
Affected users1Attacker only sees their own errors
Discoverability3Trivially found
Total9/15Medium

Step 4 — Define Mitigations

For each identified threat, define a specific control:

ThreatSTRIDEDREADMitigation
JWT not validatedSpoofing13Validate signature + expiry + claims server-side on every request
SQL injection via API paramsTampering12Use parameterized queries, run Semgrep in pipeline
No audit logging for paymentsRepudiation10Log all payment events with user ID, timestamp, amount
Stack trace in API errorsInfo Disclosure9Generic error messages in prod, structured errors in logs only
No rate limiting on loginDoS / Brute force11Rate-based WAF rule + account lockout after N failures
User can set own role in JWTElevation14Never trust client-provided role claims — look up role from DB

Step 5 — Threat Model for the MindCraft App

Let’s apply this to MindCraft specifically.

Architecture: React frontend → API Gateway → ECS backend → RDS + S3 + ElastiCache → deployed on AWS via Terraform

Trust boundaries identified:

  1. Internet → CloudFront/WAF
  2. Public subnet (ALB) → Private subnet (ECS)
  3. ECS → RDS (DB subnet)
  4. ECS → S3/ElastiCache/Secrets Manager (via VPC endpoints)

Top 5 threats identified:

#ThreatCategoryPriorityMitigation
1IDOR — user accesses another user’s resources by guessing IDsElevationCriticalEnforce ownership check on every resource lookup
2Insecure file upload — user uploads malicious file to S3TamperingHighValidate file type + size, scan with Lambda post-upload, serve via CloudFront not S3 direct
3Secrets in environment variablesInfo DisclosureHighMove all secrets to Secrets Manager, use ECS secrets injection
4ECS task with overly broad IAM roleElevationHighLeast privilege IAM role scoped to specific S3 bucket and secret ARN only
5No rate limiting on password reset endpointDoS / EnumerationMediumWAF rate rule + CAPTCHA on password reset

[SCREENSHOT]A completed threat model table in a spreadsheet or Notion showing the threat name, STRIDE category, DREAD score, and mitigation for the MindCraft application — at least 8-10 rows


Threat Modeling Tools

OWASP Threat Dragon

Free, open-source web-based tool:

1
2
docker run -it -p 3000:3000 owasp/threat-dragon
# Open http://localhost:3000

[SCREENSHOT]OWASP Threat Dragon UI in browser showing a DFD diagram being built with the threat list panel on the right showing identified STRIDE threats for a selected component

Microsoft Threat Modeling Tool

Free Windows tool with automatic STRIDE threat generation from DFDs:

  • Draw components using the templates
  • The tool automatically generates STRIDE threats for each element
  • Export to Word/Excel for documentation

Lab — Threat Model Your Blog Infrastructure

Objective: Apply STRIDE to the mhdomer.github.io Jekyll blog + GitHub Actions pipeline.

Components to model:

  • GitHub repo (source code + posts)
  • GitHub Actions (CI/CD pipeline)
  • GitHub Pages (hosting)

Draw the DFD:

  1. You (author) → GitHub repo
  2. GitHub Actions → builds Jekyll site
  3. GitHub Pages → serves to readers
  4. Reader browser → GitHub Pages

Apply STRIDE to each flow and component:

ComponentThreatFinding
GitHub repoSCan someone push to main without review? — branch protection enabled?
GitHub repoTCan pipeline files be modified to exfiltrate secrets? — workflow permissions scoped?
GitHub ActionsIAre secrets printed in logs? — use masked secrets only
GitHub ActionsECan a PR modify a workflow and run it with elevated permissions? — require approval for fork PRs
GitHub PagesDCan someone take down the site? — GitHub Pages uptime dependent on GitHub
GitHub PagesIIs any sensitive info in the published posts? — review before publishing

[SCREENSHOT]A simple DFD drawn for the blog pipeline showing the four components with data flow arrows and trust boundaries, annotated with at least 3 STRIDE threats


Key Takeaways

  • Threat modeling is the only proactive security activity — everything else is reactive
  • STRIDE gives you a systematic way to not miss threat categories — work through each letter for each component
  • The DFD is the foundation — if the diagram is wrong, the threat model is wrong
  • Prioritize with DREAD — not all threats are equal; fix Critical ones first
  • A threat model is a living document — update it when the architecture changes
  • Even a simple threat model (30 minutes on a whiteboard) catches more than no threat model

References


You can find me online at:

My signature image

This post is licensed under CC BY 4.0 by the author.