Guides · Interview formats and question types

The threat modeling interview question: STRIDE applied to one real system

2026 · ~8 min read · OfferPilot AI

The question is almost never "define STRIDE". It is "here is a system, threat model it", and the grader is watching whether six letters turn into named attacks on the boxes drawn in front of you. So draw the system first, walk each flow that crosses a trust boundary, produce one concrete threat per letter, and defend each threat at more than one layer with a mechanism you can name. Reciting the acronym and adding "validate input, encrypt data, least privilege" passes a screening call and dies in a senior loop.

Draw the system before you say a single letter

Take a file upload service, because it touches every letter and almost every candidate has built one. A B2B product where tenants upload documents and images. The flows are: browser to an API gateway that terminates TLS and validates a JWT; the upload service returns a presigned PUT to a quarantine bucket; the object lands and fires an event onto a queue; a scanner worker pulls the bytes, runs a signature scan and a content sniff, re-encodes images, copies clean objects to a serving bucket and writes a metadata row to Postgres; downloads leave through a CDN behind signed URLs.

Now say the trust boundaries out loud, because that is where the threats live and where the interviewer is scoring coverage:

  • Internet to edge. Everything the client sends is a claim, including the filename, the size and the Content-Type.
  • Tenant to tenant. One bucket and one database hold many customers, so isolation is a control you implement, not a property the architecture gives you.
  • Data into a parser. The scanner and the image resizer read attacker supplied bytes. This is the boundary juniors never draw.
  • Serving origin to browser. A stored file that executes on your own domain is a same origin problem, not a storage problem.

Name the assets too: the file bytes, the metadata row, tenant isolation itself, and the worker's cloud credentials. A STRIDE pass with no asset list produces a flat list nobody can rank.

STRIDE run against that system, letter by letter

Six letters, one specific attack each. None of these sentences would fit any other system, which is the point.

LetterThreat on this upload serviceWhat the attacker gets
Spoofing A presigned PUT URL leaks through a Referer header, a proxy log or a support ticket. It is a bearer token with no identity attached. Separately, the gateway validates a JWT without pinning alg, iss and aud. Writes into another tenant's prefix, as that tenant.
Tampering The client sends image/png for an SVG carrying script, or puts ../ in a filename that gets used to build the object key. The metadata row is patched through an object reference the API never checks against the caller's tenant. Stored cross site scripting on the serving domain, and cross tenant overwrite of a real document.
Repudiation Only the bucket owner appears in the storage access log, so nothing records which principal minted the presigned URL or which user triggered the delete. An incident nobody can attribute, and a customer dispute you cannot answer.
Information disclosure Sequential object keys, plus a signed URL with a seven day expiry sitting in a Slack thread. GPS coordinates left in image EXIF. A stack trace returning the internal bucket name and region. Enumeration of other tenants' files, and reconnaissance for the next step.
Denial of service A 5 GB body buffered before any check runs. A decompression bomb that expands to tens of gigabytes inside the resizer. A flood of tiny uploads that backs the scan queue up. Clean files never publish, and the worker fleet falls over while the API keeps accepting work.
Elevation of privilege A parser bug in the image pipeline gives execution inside a worker whose role can read every prefix. Or an import from URL feature fetches http://169.254.169.254/ and returns instance credentials. Reads across every tenant, and in the SSRF case a role that may reach well past this service.

Layered mitigations, with names attached

One control per threat is a junior answer. Say where the control sits, and say what still gets through it.

At the edge, before a body is buffered

A hard body size cap at the proxy, client_max_body_size in nginx or the equivalent limit on the load balancer, so an oversized upload is refused before it reaches application memory. A per tenant quota and a token bucket rate limit on the presign endpoint, since the cheap request to abuse is the one that mints URLs. The JWT validated against a JWKS endpoint with algorithm, issuer and audience pinned, never a shared secret, and never with alg read out of the token.

Never let the client name the file or the type

Generate the storage key yourself, a UUID under tenant/{tenant_id}/, and keep the user's filename as a column rather than a path component, which deletes traversal as a category instead of filtering for it. Presign that exact key with a five minute expiry and a content length range condition, so the URL cannot be reused for a different object or a bigger one. Sniff the real type server side with libmagic through python-magic, or with Apache Tika, then allowlist, and treat the client's Content-Type as a hint you throw away.

Parse hostile bytes inside something disposable

The scan and transform worker gets no network egress and a role scoped to the quarantine prefix only, so a parser exploit lands somewhere with nothing worth stealing. Re-encode images rather than validating them, with libvips or an ImageMagick policy.xml that disables the coder delegates, which kills the SVG script payload and strips EXIF in the same pass. Set explicit decode memory and pixel limits so a compression bomb hits a ceiling instead of a timeout. For import from URL, resolve the hostname first, reject loopback, link local and RFC1918 ranges, then pin and re-check the resolved address to close the DNS rebinding window, or push the whole feature through an egress proxy with an allowlist.

Split the buckets and make deletion provable

Quarantine and serving are separate buckets with public access blocked at the account level. Server side encryption, versioning, and object lock on the serving bucket, so a delete is recoverable and repudiation stops being free. Authorization on read runs against the metadata row and the caller's tenant, never against the shape of the key, because a key that looks unguessable is not an access control.

Serve from a domain that owns nothing

Downloads go out from a separate origin such as files-usercontent.example.net, with no cookies and no session ever scoped to it, so a file that does execute has no same origin data to reach. On every response: Content-Disposition: attachment, X-Content-Type-Options: nosniff, a Content-Security-Policy of sandbox; default-src 'none', and the content type you sniffed rather than the one they sent. Signed URLs measured in minutes and bound to one object.

Log the thing that will be disputed

An append only audit event for every presign and every delete: principal, tenant, object key, content hash, request id. Alert on scan failure rate, on upload volume per tenant against that tenant's own baseline, and on any spike of denied cross prefix reads, which is what stolen worker credentials look like from the outside.

The junior bar and the senior bar, said plainly

Both columns below are correct. Only one of them earns a senior rating, and the difference is not vocabulary. It is a named mechanism with a second layer behind it.

LetterPassing answerSenior answer
S"Authenticate the user."Presign one key for five minutes with a length condition, pin JWT alg, iss and aud, and say out loud that a leaked URL is a bearer token, which is why the short TTL is the actual control.
T"Validate the input."Server generated keys so traversal cannot exist, magic byte sniffing over the declared type, and re-encoding instead of validating, because a validator that accepts an SVG has already lost.
R"Add logging."Append only audit with principal and content hash, plus object versioning and object lock, so the storage layer can contradict a customer who says they never deleted it.
I"Encrypt the data."Cookieless serving origin, nosniff, attachment disposition, short signed URLs, EXIF stripped during re-encode, and no bucket name in any error body.
D"Rate limit it."Size cap at the proxy before buffering, decode limits for compression bombs, and queue isolation so scan backpressure degrades publishing instead of taking the upload path down.
E"Least privilege."A worker with zero egress and a prefix scoped role, ImageMagick delegates disabled, and SSRF filtering applied after resolution rather than before, so rebinding does not walk straight to the metadata endpoint.

The left column is the OWASP Top 10 recited from memory. Interviewers assume that knowledge, so a round spent there reads as having nothing underneath it. Two further things separate the columns. Seniors name the residual risk: signature scanning catches known malware and does nothing at all about a stored XSS payload, so it is not an answer to Tampering. And seniors rank. Close with something like this: "the stored XSS on the serving origin and the SSRF in import from URL are what I fix this quarter, because both are full compromise from a single unauthenticated request. The compression bomb is a paging incident, not a breach, so it sits behind them." If they want a scoring model, DREAD is fine, as long as you say the numbers are subjective and you use them to sort, not to justify.

Where a live copilot is the wrong tool for this round

Threat modeling is the security round that live assistance helps least with. You are drawing, the interviewer interrupts mid sentence to ask why an extension allowlist is not enough, and the whole answer is anchored to a diagram whose shape you chose. Generic STRIDE text arriving on a screen cannot know you drew a quarantine bucket, and the follow up question lands on your reasoning rather than on the list.

  • OfferPilot AI runs on Windows 10 and 11 only. No macOS, no Linux, no mobile, no browser extension. On a Mac, none of it is available to you.
  • Capture exclusion covers screen sharing and screen recording, nothing more. The overlay is excluded from screen capture at the operating system level, so it does not appear in Zoom, Teams, Meet, OBS or screenshots, while staying visible on your own monitor. It does nothing about a webcam, a lockdown browser, eye tracking, a second device camera, or a person watching you at a physical whiteboard, and plenty of threat modeling rounds are exactly that.
  • The rules belong to the company. Some interviews permit documentation and AI assistance and some do not. Read the instructions, and ask when they are ambiguous.
  • This is the answer to memorize instead. One system modeled properly, with the header names and library names attached, transfers to almost every application security prompt you will be given.

Practise on your own architecture, not a generic one

Run this exact pass on a service you actually shipped, then again on a payment webhook receiver and on an internal admin tool, and hold yourself to twelve minutes. Coverage comes from the six letters. The rating comes from the specific header, the specific library, and the second layer behind each control. The question banks are a reasonable source of systems to run it against, and the company Q&A generator builds a bank for one company and role, which matters here because a payments company and an infrastructure company push on different letters. OfferPilot AI is free for 5 minutes a day with no card, and it meters listening time only.

Related guides

Walk into the security round with the specifics ready.

Build a company-specific question bank, then rehearse the STRIDE pass out loud until it fits in twelve minutes.