PXL Security LTD, Sofia, Bulgaria Offensive security since 2014[email protected]
Secure DevelopmentThreat Modelling

Shift left, properly: threat modelling engineers actually use

By PXL Security11 May 202313 min read

"Shift left" became a slogan, and like most slogans it lost its meaning. Done badly, threat modelling is a day of drawing diagrams that get filed and forgotten. Done well, it's the cheapest security activity you can run: a focused conversation that catches design flaws before they're built, when they cost almost nothing to fix.

Why design beats detection

The cheapest vulnerability is the one that never ships. A missing authorization boundary caught at design is a sentence in a document; the same flaw caught in a penetration test is a finding, a sprint, and a retest; caught in production, it's an incident. Threat modelling moves the catch as far left as it goes — to before the code exists.

A lightweight model engineers use

You don't need a formal methodology to start. Four questions, asked of a feature or a system, get you most of the value:

  1. What are we building? A simple diagram of components, data flows and trust boundaries. Where does data cross from "less trusted" to "more trusted"?
  2. What can go wrong? Walk each trust boundary and data flow. Spoofing, tampering, information disclosure, elevation of privilege — who could abuse this, and how?
  3. What are we going to do about it? For each real threat, a mitigation or an accepted risk. Concrete, owned, tracked.
  4. Did we do it? Verify the mitigations landed — ideally tested, not assumed.

Keeping it useful

  • Time-box it. An hour on a feature beats a week on a system diagram nobody revisits.
  • Do it when it's cheap to change. At design and major-change time, not after the architecture has set.
  • Make it the team's, not a document's. The output that matters is shared understanding and a short list of owned mitigations.

Threat modelling isn't a deliverable to admire. It's a habit of asking "what could go wrong here, and who owns stopping it?" — early enough that the answer is still cheap.

Where to start if you’ve never done it

Don’t try to threat-model the whole system on day one — you’ll produce a diagram and abandon the habit. Pick one upcoming feature that touches sensitive data or money. Spend a single hour with the engineers who’ll build it and work the four questions above. Write each mitigation as a ticket with an owner. That one session, repeated for every significant feature, delivers more real security than any heavyweight programme you’ll quietly drop after a quarter. The goal is a habit, not a document.

Abuse cases alongside use cases

Here’s the lightest-weight way to make threat modelling stick: for every user story, write one abuse story. “As an attacker, I want to read another customer’s invoice.” “As an attacker, I want to approve my own refund.” It turns the abstract “what could go wrong” into concrete, testable statements, and it slots directly into the way teams already plan work — no new ceremony required.

STRIDE, applied per element (not per app)

The four-question model gets a team moving; STRIDE gives it depth when a design is non-trivial. The mistake is to ask "is this app vulnerable to spoofing?" as one lump. STRIDE earns its keep when you walk it per element: take each process, data store, data flow and external entity in turn, and ask only the categories that actually apply to that element type.

  • Processes are exposed to all six: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege.
  • Data flows care about Tampering, Information disclosure and Denial of service — a message in transit cannot elevate its own privilege.
  • Data stores take Tampering, Information disclosure, Denial of service, and Repudiation where the store is a log.
  • External entities (users, third-party services) are about Spoofing and Repudiation.

This turns a vague anxiety into a finite checklist. For a token-issuing endpoint you ask: can the caller be spoofed (weak auth), the token tampered with (unsigned claims), the issuance repudiated (no audit record), the signing key disclosed? Each "yes, and nothing stops it" is a finding with a named mitigation, not a worry.

Data-flow diagrams and trust boundaries, done right

STRIDE is only as good as the diagram under it, and most diagrams are too clean. The one line that matters is the trust boundary: the point where data crosses from something you control to something you do not, or from one privilege level to another. Threats cluster on those crossings. A DFD with no boundary lines is a box diagram that will mislead you.

Keep it at one level of detail — the level where boundaries are visible but implementation noise is not. Draw processes, stores, flows and the external entities that feed them, then draw the boundaries last and label what changes across each one (authentication, encryption, input validation).

[ Browser ] --(1) HTTPS--> | TB:network | --> [ API gateway ]
                                                      |
                            | TB:auth/privilege |     v
                                                [ Order service ] --(2)--> [( Orders DB )]
                                                      |
                            | TB:third party |        v
                                              [ Payment provider ]

Every numbered flow that crosses a boundary is a line in your STRIDE pass. If a flow never crosses one, it is usually not where your time goes.

Note. If two people draw the same system and disagree on where the boundaries are, you have found a real ambiguity in ownership or trust — resolve that before writing a single mitigation.

Attack trees and honest risk ranking

Once you have threats, you must prioritise, and this is where numeric scoring quietly fails. Attack trees prioritise by making the adversary's path explicit: put the goal at the root and decompose it into AND/OR sub-goals until you reach concrete, costed actions. The cheapest complete path — the weakest OR branch — is what an attacker actually takes, and that is what you fix first.

GOAL: read another tenant's orders
 OR-- exploit missing tenant check on order ID   [cheap, remote]
 OR-- obtain a valid token for another tenant
      AND-- find token in client logs
      AND-- replay before expiry                  [needs local access]

Resist DREAD-style scoring. Averaging Damage, Reproducibility, Exploitability, Affected users and Discoverability into one number gives false precision: the inputs are guesses, the scale is uncalibrated, and two assessors rarely land within two points of each other. Worse, averaging lets a catastrophic-but-rare item and a trivial-but-constant one collapse to the same middling score. Prefer a coarse, defensible ranking — likelihood against impact on a three-band scale, tied to the cheapest attack path — and record the reasoning, not just the digit. A ranking you can argue beats a score you cannot reproduce.

Threat modelling as code, and linking to tests

A model that lives in a slide deck dies at the first design change. Keep it in the repository beside the code it describes — a diagram-as-code DFD and a threat list in a versioned text file — so it diffs in review and a pull request that adds a new data flow is expected to update it. This is "threat modelling as code": the artefacts are plain text, they are code-reviewed, and a CI check can flag a model untouched for N releases or a new external endpoint with no corresponding entry.

The step that makes mitigations real is linking each threat to a test. A mitigation with no test is a hope. Give every threat a stable identifier and reference it from the test that proves the control holds — the missing-tenant-check threat maps to an automated test that requests another tenant's resource and asserts a 403. Now a regression that reopens the hole fails the build, traceability runs both ways (threat to test, test to threat), and your coverage gap is simply the threats with no linked test. That list, not a scoreboard, is the honest measure of whether the model did anything.

Want threat modelling that sticks?

We run threat modelling and secure code review alongside your engineers — practical, time-boxed, and tied to real mitigations.

Talk to an engineer