Security insights

Threat Modeling Without the Jargon: A Practical Primer for Product Teams

Forget the methodology books. Put down the certification study guide. Here's an actual threat modeling session, in real time, on a real-feeling product — with the questions we ask, the answers that come back, and the moment everyone in the room suddenly sees the same thing differently.

BU
BugSwagger Team

Most articles about threat modeling explain what threat modeling is. This one will run one, on the page, in something close to real time.

The reason I want to do it this way is that threat modeling is one of those activities that sounds intimidating in the abstract and embarrassing once you see how simple it actually is. The methodology books make it look like a discipline that requires years to master. The reality is that a useful threat-modeling session is a structured conversation that takes about an hour, requires a whiteboard, and produces a list of specific things to do.

I want you to come along for the conversation. Imagine you and I are sitting in a conference room, with a whiteboard between us, and we're going to threat-model a product feature your team is about to ship. I'll play the security person. You play the rest of the team. Read this as if you're in the meeting.

The product, in two sentences

"We're building a feature that lets users share files with anyone via a link. The link works without the recipient needing an account."

Good. This is the kind of feature every consumer SaaS ships at some point. Let's draw it on the whiteboard.

Step one: what are we working on (whiteboard time)

I'm drawing four boxes.

The first box is the sharing user — the logged-in customer of our app who creates the share link. They have a session with our backend.

The second box is our backend — it generates the share link, stores it in a database, and serves the file when the link is requested.

The third box is the file storage — let's say S3 — where the file actually lives. The backend has IAM credentials to read it.

The fourth box is the recipient — anyone with the link. They're unauthenticated. They could be a person the sharer intended, or anyone the link reached.

I draw arrows. Sharer → backend (creates link). Backend → storage (uploads or references file). Recipient → backend (requests link). Backend → storage (fetches file). Backend → recipient (serves file).

I draw a dotted line across one of the arrows: the trust boundary. On one side, our sharer is authenticated. On the other side, the recipient is whoever clicked the link. The trust boundary is the most important thing on the whiteboard — it's the line where assumptions stop holding.

You — the team — look at the diagram. You're already seeing things you hadn't fully thought about. Good. That's the entire point of step one.

Step two: what can go wrong (the walk)

Now we walk the diagram. I'll ask the same five questions about each box and each arrow, in turn. The questions are:

  1. Who can reach this?
  2. What does it trust?
  3. What happens if its inputs are malicious?
  4. What happens if its outputs go to the wrong place?
  5. What happens if it crashes, hangs, or comes back up in a weird state?

Let's start with the share link itself, the thing the backend generates.

Me: What's the link look like?

You: It's https://app.example.com/share/{token}. The token is a random string.

Me: How long is the token?

You: Eight characters, alphanumeric.

I write on the whiteboard: Token is 62^8 = 2.18 × 10^14 possibilities. Then I write: If attacker can probe 100/sec, expected to find one valid link in ~70,000 years.

You start to relax. I keep going.

Me: What if the attacker is targeting a specific user's links? They iterate over the share-creation API and watch for collisions?

You: The share-creation API is only available to authenticated users.

Me: Right, but is there rate-limiting on the link-lookup endpoint? The recipient endpoint, the one that takes a token and returns a file?

You: (Pause.) I don't think so.

I write on the whiteboard: Risk 1: Token brute-force at scale, unrate-limited. Action: rate-limit link lookups by IP and by failed-token frequency.

This is what a threat-model walk feels like. We didn't invent the threat. We walked the diagram and applied a simple question. The question — "is this rate-limited?" — surfaces a real gap your team would otherwise have shipped.

Let's keep walking.

Me: What does the link expire on?

You: Forever. Until manually revoked.

Me: What happens when the sharing user leaves the company, or revokes their account, or has their account terminated? The link they created keeps working?

You: Yeah, I guess it does. The link is independent of the user.

I write: Risk 2: Link survives sharer account termination. Action: link expires when user account is deactivated.

Me: What's in the file? Is there any limit on what kinds of files can be shared?

You: No, any file.

Me: What if someone shares a 100GB file? What if they share a million files? What if they share illegal content and now we're hosting it?

You: ...we hadn't talked about this.

I write: Risk 3: Abuse vectors — large files, mass sharing, illegal content. Action: per-account quotas, content scanning, takedown process.

This isn't a security risk in the narrow sense. It's a product-level risk that the threat model surfaces because we're systematically asking what can go wrong. Some of the most important things threat modeling surfaces are not bugs. They're missing product decisions.

Crossing the trust boundary

Now the most important arrow on the diagram. The recipient — unauthenticated, unverified — making a request to the backend with a token.

Me: What does the backend do when it receives a request to /share/{token}?

You: Looks up the token in the database. If it exists, fetches the file from S3, serves it back.

Me: The backend has S3 credentials with read access to all files, right? It uses those to fetch the requested file?

You: Yes.

Me: So if there's a bug in the token-lookup code — let's say SQL injection, or the wrong query, or any kind of confused-deputy issue — the attacker could potentially request files other than the one the token was for?

You: Theoretically.

Me: What if instead of a token, the user submits /share/' OR 1=1 --?

You: We use parameterized queries.

Me: Good. What about ../../etc/passwd?

You: The token is just a database key, not a file path.

Me: Okay. What's the file name in the response — is it controlled by the sharer? What if they upload a file called resume.pdf.exe? Or one with HTML in the filename that gets reflected back in the page?

You: Pause.

I write: Risk 4: Filename injection / dangerous file types via Content-Disposition header. Action: sanitize filenames, set Content-Type strictly, set X-Content-Type-Options: nosniff.

Notice the pattern. I'm not finding bugs you have. I'm finding decisions you haven't made. The threat model is forcing you to either make the decision now or write down that you've decided not to. Both are better than having the decision made for you in production.

The "what about the recipient" turn

I draw a circle around the recipient.

Me: The recipient gets the file. What if the file the sharer uploaded was malicious — a virus, a phishing PDF, a fake invoice? Are we, the platform, hosting it?

You: Hmm.

Me: What if a phishing campaign uses our share links to deliver malware? "Click here to view your invoice — link is to app.example.com, so it looks safe." Our domain is now the delivery infrastructure for someone else's phishing.

I write: Risk 5: Platform-as-phishing-delivery. Action: malware scanning on upload, warning page for unverified recipients, takedown SLA.

Me: What if the link gets shared in a context that fetches it automatically? Slack will preview it. Gmail's safe-link scanner will fetch it. Corporate proxies might fetch it. Does our backend treat those fetches as "the file was downloaded"?

You: Yes. We count downloads.

Me: So the sharer thinks the file was downloaded, but actually it was just previewed by a bot. Acceptable? What about features that fire on first download — like "delete after first view"?

I write: Risk 6: Bots and automated fetchers triggering "view" semantics. Action: distinguish bot fetches from human, or require user interaction click-through before download.

We could keep walking. There are at least another dozen things to surface — what if the file storage has its own vulnerabilities, what if the database has bugs, what if the backend gets compromised and starts serving the wrong files to the wrong people. But for an hour-long session, six risks is a strong return.

Step three: what are we going to do about it

Now we triage. I draw three columns on the whiteboard: Fix now, Fix later, Accept.

Risk 1 (rate-limit lookups) — fix now. It's one engineer-day, and the attack is real.

Risk 2 (link survives account termination) — fix now. Compliance might require it; product certainly wants it.

Risk 3 (abuse vectors) — fix later, with a real product conversation. Per-account quotas can ship in a sprint. Content scanning is a bigger decision involving vendors and budget.

Risk 4 (filename injection) — fix now. It's a one-hour change to set Content-Type strictly and sanitize names.

Risk 5 (phishing delivery) — accept for now, document, and revisit when the product is larger. Real risk, but mitigation is non-trivial.

Risk 6 (bot fetches) — accept for v1, fix in v2. Edge case for current scope; matters more when we add the "delete after view" feature.

Each line gets an owner and a deadline. The output is six tickets in your project tracker, three with this-sprint deadlines, two with next-quarter deadlines, one with a documented decision to not address now.

That is the deliverable. Not a 30-page document. Six lines, owners, deadlines.

Step four: did we do a good job

The hardest part of threat modeling — and the one most teams skip — is the followup. Six months later, you should go back to the document and ask: did we ship the mitigations we said we would? Did the assumptions we wrote down still hold? Has the product changed in ways that invalidate the model?

If you don't do step four, the threat model is a one-time exercise that ages out of relevance. If you do it, the threat model becomes the team's shared mental model of the system's security posture. That's the actual deliverable. The document is just where it lives.

The patterns from our hour

Look back at what we did. We drew a system. We walked the diagram and asked five questions about each piece. We surfaced six risks, none of which required exotic knowledge. We triaged them in three buckets. We assigned owners.

That's the entire methodology. The books that take 400 pages to explain it are not wrong — they're complete. But for a team that wants to start, you don't need the 400 pages. You need the whiteboard, the hour, and the discipline to actually do it.

Where teams get stuck (and what to do)

The two failure modes we see most often:

First, the team treats threat modeling as a brainstorm. They get a room full of people and ask "what could go wrong?" The answers are creative and almost useless. The discipline is to walk the diagram, applying the same five questions to each piece. The structure is what produces the findings.

Second, the team produces a beautiful document that nobody reads. The fix is to produce a small artifact — a list of risks with owners — instead of a comprehensive one. The 30-page document is impressive. The six-line ticket list is what gets fixed.

When to do it

Two highest-value moments. Before a major design decision, when changing direction is cheap. Before a launch that crosses a new trust boundary — going from internal-only to public, adding payments, adding multi-tenancy, integrating with a new platform. Each one is an attack-surface expansion that should be deliberate.

The rest of the time, threat modeling is a habit. Five minutes at the start of a design review. A quick walk through the diagram of a new endpoint. A pre-commit conversation about what could go wrong. Small, often, embedded in the team's workflow — that's what works.

Who should be in the room

Engineers who'll build the system. The PM who knows what it's for. Someone who's seen production incidents (ops, support, on-call). And, if possible, someone who can play the adversary — a security person, a contractor, or an external reviewer.

The adversarial role matters. It's easy for the team that built a thing to convince itself that everything is fine. The person whose job is to break it asks better questions. If you don't have a security person, designate someone on the team to play the role for the session. It works better than you'd expect.

A note on Adam Shostack's four questions

The structure I used is based on Adam Shostack's four-question framework: What are we working on? What can go wrong? What are we going to do about it? Did we do a good job? Adam wrote the book on this (literally — it's called Threat Modeling: Designing for Security). If you want the deeper treatment, that's the book. For starting, the four questions are enough.

One last thing

You finished the session. You have six tickets. Your team is leaving the room more aligned on the security implications of the feature than they were when they came in. The PM has product decisions to make that they wouldn't have surfaced without the structure. The engineers have a clearer mental model of what they're building.

That, more than any artifact, is what threat modeling produces. It's a shared conversation that turns assumptions into decisions. The shared conversation is the value. Everything else — the documents, the diagrams, the methodologies — is in service of having it.

If your team has never done one, schedule the next one for an hour next week, on whatever feature is most actively in design. The first one will feel awkward. The third one will feel natural. By the tenth one, your team will be making different design decisions, earlier, because the conversation will have changed how they think.

That's the actual transformation. The whiteboard is just where it starts.

Found this helpful?

Want a hand-tested assessment for your own stack?

Tell us what you're protecting — we'll respond within one business day with a scoped proposal written by a pentester.