skip to content

Your STRIDE per-element sheet covers every element on the diagram - what threats can it still miss?

level: seniorimportance: should knowfreq 52%

answer

  1. the grid asserts things about boxes
  2. nothing on the page owns a relationship
  3. the trust one side places in the other
  4. elements nobody drew get no row
  5. a full grid reads as a guarantee

basics

~20 s

A per-element sweep only asks what each element can suffer on its own. Threats that live in the relationship between elements, in the trust one component places in another, and in elements nobody drew, produce no row at all.

solid answer

~50 s

Completeness on a per-element sheet means every element got the letters its type allows, not that every threat is on the page. Three gaps survive a full sheet. First, crossing threats: the sheet never asks what happens when a request moves from one trust level to another, because that threat belongs to the relationship rather than to either box - a separate interaction-oriented pass exists precisely to catch it. Second, trust assumptions: a component that accepts whatever a neighbour sends because "it is internal" has no cell for that. Third, everything that is not on the diagram - an admin path, a backup job, an operator with console access - gets no row because it has no element. The danger is presentational: a tidy, fully populated grid reads as coverage, so I state explicitly what the pass covered and what it did not.

go deeper

for a junior

Know that finishing every cell means every element was visited, and that a threat can be real even when no cell on the sheet describes it.

for a middle

Be able to explain why the grid's structure - one row per element - is what discards relationship threats, and name the assumptions list as the place those findings go instead.

for a senior

Given a design and a finished sheet, point at a specific threat the sheet cannot hold, say which gap type it is, and say what pass or review you would run next.

for a principal

Decide how much analysis a delivery process buys: when an element sweep is the right stopping point, when a second pass is warranted, and how to report coverage honestly to people who read a grid as assurance.

## What "complete" means on a per-element sheet A STRIDE-per-element pass is complete when every element on the diagram has been visited and every category its type allows has been answered - either with a concrete threat or with a written reason it does not apply. That is a real and useful property: it is auditable, it is hard to skip quietly, and it stops the common failure of modeling only the parts of a system somebody finds interesting. It is not the same property as "every threat to this system is written down", and conflating the two is the characteristic senior mistake with this technique. The sheet's shape - one element per row, letters as columns - makes an assertion about elements, so anything that is not a property of a single element has nowhere to be written. ## Worked example: a podcast-hosting publish flow A hosting service takes an uploaded audio file, runs it through a transcoding process, and writes renditions to a CDN origin store from which listeners are served. The attacker to assume is an anonymous internet user, and the asset at stake is content IP - unreleased episodes and paid-subscriber-only audio. The per-element sheet fills in neatly. The transcoding process gets all six: it can be impersonated, its job parameters corrupted, its actions unlogged, its temporary files leaked, its queue exhausted, and its worker made to run at a higher privilege than the job requires. The CDN origin store gets tampering, information disclosure and denial of service: renditions overwritten, unreleased audio read, the bucket saturated. Every cell has a sentence in it. Nothing is blank. Now read what is not there: - **The crossing threat.** A publish request originates on the public internet and ends up as work executed inside the internal zone. The threat is that the transcoder treats a request as trusted because of where it arrived from, not because of what authenticated it. No cell asks that question, because the threat is a property of the relationship between the two elements, not of either one. - **The inherited trust.** The origin store serves an object because the transcoder wrote it, and the transcoder wrote it because the upload service accepted it. Nobody re-checks entitlement, so an unreleased episode is one guessable path away from a listener who never paid. Every element individually looks correct. - **The undrawn element.** The re-encode retry job, the support tool that fetches a rendition to reproduce a complaint, the backup copy of the origin bucket. None of them are on the diagram, so none of them have rows, and the sheet reports full coverage regardless. - **Sequence and state.** "Publish, then unpublish, then republish" abuses live in the ordering of operations, not in any single box. ## Why the gap is structural, not sloppiness Per-element analysis buys its low cost by decomposing the system into independent pieces. That decomposition is exactly what discards relationships. You cannot fix it by trying harder inside the same grid; you fix it by running a pass whose unit of analysis is the interaction rather than the element, and by reviewing the diagram itself for things that were never drawn. Those are different activities with different costs, and choosing between them is a scoping decision. ## What to do about it in practice - **Say what the pass covered.** Write the scope statement next to the sheet: which elements, which diagram version, which pass type. A grid without that reads as a guarantee it cannot make. - **Record assumptions as first-class items.** "The transcoder assumes upstream authenticated the publisher" is not a STRIDE cell, but it is the highest-value line on the page. Keep an assumptions list beside the grid and treat each unverified one as an open item. - **Review the diagram for absence.** Ask what operates on these elements that is not drawn: admin paths, batch jobs, support tooling, recovery procedures, human operators. - **Do not confuse full cells with low risk.** The sheet says nothing about which of these threats matters most; rating is a separate step with its own inputs. ## The interview signal A candidate who says "we walked every element, the model is complete" has learned the mechanics and not the limits. The answer that lands names the gap type - relationship threats, trust assumptions, undrawn elements - gives one concrete instance from the design in front of them, and says what they would do next rather than treating the grid as the deliverable.

  • How do you keep a fully populated sheet from being read as an assurance sign-off?
    Publish the scope with the sheet: which diagram version, which elements, which pass type, and an explicit list of what was not analysed. Then keep an assumptions list alongside the grid, because unverified trust assumptions are the findings the grid structurally cannot hold. Reviewers who see the limits stated stop treating the grid as a certificate.
  • If the per-element pass is structurally incomplete, why run it at all?
    Because it is cheap, teachable and auditable. It guarantees nobody skipped the boring elements, it gives newcomers a way to contribute without deep security experience, and it produces a written record you can diff when the design changes. Its limits argue for following it with another pass, not for skipping it.
  • What is the fastest signal that a diagram is missing elements?
    Ask who operates the system rather than who uses it. Admin consoles, batch and retry jobs, support tooling, backup and restore paths and vendor access almost never make it onto a first diagram, yet they usually hold the highest privilege in the design. Any of them that has no element also has no threat rows.

saying these in an interview costs you the question

  • Treats a fully filled grid as proof the model is complete
  • Says a missing threat means someone did the sweep carelessly
  • Cannot name a threat type that has no per-element home
  • Confuses coverage of elements with coverage of risk
  • Ignores admin, backup and support paths that were never drawn

context