Threat Modelling
Threat modelling is the cheapest security activity there is. Before you build, you sit down and ask: "What could go wrong, and who would make it go wrong?" An hour of careful thinking at design time often prevents a vulnerability that would otherwise take a sprint to fix and a breach to find.
You do not need a heavy framework to threat-model. You need four honest questions: What are we building? What can go wrong? What will we do about it? And did we do a good enough job? Walk through the data and trust boundaries of a feature, imagine an attacker at each one, and write down what you will do about the threats you find.
STRIDE is a useful reminder — Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege. But the goal is not process for its own sake. It is to catch the unsigned webhook, the missing tenant check, or the forgeable claim while it is still a sketch. The Finperiti findings are exactly the kind of thing a five-minute threat model finds before code exists.
When and how to model
- AlwaysThreat-model new features and significant changes at design time, especially anything touching authentication, money, PII, KYC/AML decisions, or trust boundaries.
- DoDraw the data flow and mark the trust boundaries. The threats are where data crosses from less-trusted to more-trusted.
- DoWalk through STRIDE at each boundary. Can an actor spoof an identity, tamper with data, deny their action, read what they should not, exhaust the system, or gain privilege?
- DoFor each real threat, record the mitigation, or the clear, owned decision to accept the risk. A threat model is only useful if it leads to actions.
- ConsiderModelling the abuse case, not just the use case. Design for the hostile user as carefully as the honest one.
- ConsiderKeeping a light, living threat model next to the design doc, and updating it when the feature changes a lot.
Make it real, not ceremonial
- DoTurn findings into tracked work — tests, controls, or backlog items — so the model changes what gets built.
- DoPay close attention to inbound integrations and webhooks. Who can call this? How do we know it is really them? What if it is forged or replayed?
- ConsiderReusing earlier models for similar features. Most threats recur, and a shared list of "things that go wrong here" speeds up every review.
- Do notTreat threat modelling as a document to file and forget, or a box to tick at the end. Done late, it changes nothing.
- Do notAssume internal or service-to-service traffic is automatically safe. Model the insider and the compromised neighbour too.
Flow: Provider → POST /webhooks/kyc → update customer status
Boundary: internet → our trusted decision logic
STRIDE:
Spoofing → anyone can POST ⇒ verify HMAC signature
Tampering → payload altered ⇒ signature covers body
Replay → resend old event ⇒ timestamp + nonce/event-id
Elevation → forged "approved" ⇒ fail closed on bad/absent sig
This is the whole exercise. Five minutes here is exactly what would have caught the Finperiti unsigned-webhook finding, before a forged "approved" could pass someone through AML.
Self-review checklist
- AskWhere does untrusted data cross into the trusted part of this feature?
- AskFor each boundary: spoof, tamper, repudiate, disclose, deny, elevate — which ones apply?
- AskHow do I know an inbound caller is who they claim to be, and that the message is not forged or replayed?
- AskDid every real threat get a mitigation, or a clear, owned decision to accept the risk?