Adam Shostack here, with the second post in my series on the evolved threat modeling process. To summarize, what I’ve tried to achieve in changing the process is to simplify, prescribe, and offer self-checks. I’ll talk in the next post about why those three elements are so important to me. For now, let me describe the process.
One of the largest changes that we’ve made is to a simplified process (and diagram). I like to say that this looks pretty much like every other software process diagram you see today. That’s intentional. There’s only so much we can expect people to take away from a class, and making this simple and familiar helps ensure there’s room for the other important parts.
First, the “process hamster wheel,” (with apologies to Yankee Group analyst Andy Jaquith):
Now that you’ve seen the wheel, I’ll briefly describe the steps:
- Vision: Consider your security requirements, scenarios and use cases to help frame your threat modeling. What are the security aspects of your scenarios? What do your personas expect or hope doesn’t happen? What are the security goals of the system you’re building, and how do those interact with the system as it stands?
- Model: The basic idea is to create a diagram of your software, showing all trust boundaries.
a. Draw a diagram of your software. We encourage use of the DFD formalisms, which Larry Osterman describes in this post.
Essentially, the elements are
- External entities (anything outside your control)
- Processes (running code)
- Data stores (files, registry entries, shared memory, databases)
- Data flows (which connect all the other elements)
b. Draw trust boundaries between components. You can do this on a whiteboard, in Visio, or in one of the specialized threat modeling tools we’ve built. (A trust boundary is anywhere that more than one principal can access an object, such as a file or process.)
c. If your trust boundary crosses something which isn’t a data flow, you need to break it into two logical elements, or draw a sub-diagram with more details. (This is different advice: we used to tell people trust boundaries could only cross data flows. People drew them anywhere that felt right. We decided to go with what people were doing—there was important information in what they were expressing.)
d. If you need more details to express where trust boundaries are, add an additional diagram.
e. When you don’t have any more trust boundaries to draw, you’re done.
f. If a diagram doesn’t have any trust boundaries, you may have drawn too many details.
3. Identify Threats using STRIDE/element
For each element in your diagram, consider threats of the types indicated in this chart. (We’ll come back to the chart’s origins in a later post.)
There’s an important mis-conception we often see, which is that STRIDE is appropriate for use as a classification system. It’s really hard to use STRIDE to describe attacks—the impacts blend together really quickly. The most valuable use of STRIDE is to help people think about how threats have impacted elements of a design in the past. That is, it’s a framework for finding threats, not for describing them. “What if someone spoofs this host?”
Here on the SDL strategy team, we love threat modeling. We know that not everyone feels that way, and we ask teams to threat model so that they can find and mitigate threats. A threat model document with great diagrams and lots of threats isn’t very useful if you don’t take the key step of addressing the issues you find. There are four ways to do that:
a. Redesign to eliminate threats.
b. Use standard mitigations, such as those provided by OS features, to mitigate threats.
c. Invent new mitigations, understanding that this is a subtle art.
d. Accept risk, when allowed by the SDL
There are two levels of validation. The first is within each stage, the second is a validation pass at the end of the process. That end of process validation entails:
a. Make sure that the diagrams are up-to-date and accurate
b. Ensure that you have STRIDE threats per data flow that crosses a trust boundary, and for each element that such a trust boundary connects to
c. Make sure you’re mitigating each threat
i. You have a bug filed per threat that you want to mitigate. The bug should be of the form “attacker can do X. Proposed fix: Y.” You might include tradeoffs you’re making, and possibly have test plans in the bug, if you include those.
ii. You have a valid reason for each non-mitigated threat not being mitigated.
iii. All threats are in class i or ii.
5.a. On change, re-validate
This hamster wheel has a very intentional brake on it: the word change, above validate. What that means is you want to go through the process again when you make changes that need to be on the diagram. Checking to see if your diagrams change is a relatively simple check that allows people to track changes against their threat model as their design iterates.
In the next post, I’ll talk about the reasoning behind the design, and offer up some process tools that anyone can use to make a process more user-friendly.