1. The CIA Triad
Almost every security decision, from a single line of firewall config to a company's entire incident-response plan, is protecting one (or more) of three properties. Together they're the CIA triad — not the agency, the checklist:
Confidentiality # only the people who should see data, can see it
Integrity # data isn't modified without authorization or detection
Availability # authorized users can actually get to the system when they need it
A breach rarely takes down all three at once — it usually targets one specifically, and that tells you a lot about what defense actually matters:
# Confidentiality attack: a stolen database of customer emails and passwords
# Integrity attack: an attacker quietly changes a bank transfer's destination account
# Availability attack: a DDoS flood takes a checkout page offline during a sale
Every week from here on maps back to one or more of these. Encryption protects confidentiality. Hashing and digital signatures protect integrity. Redundancy, rate-limiting and DDoS protection protect availability. When you're not sure why a control exists, asking "which of the three is this protecting?" almost always clarifies it.
Locking a system down for confidentiality (strict access controls, aggressive session timeouts) often costs availability or usability. There's rarely a "maximize all three" answer — the job is choosing the right trade-off for what the system actually protects.
2. Threats, Vulnerabilities & Risk
These three words get used interchangeably outside security conversations, but they mean specific, different things once you're threat modeling:
Threat # someone or something that could cause harm (an attacker, a bug, a flood)
Vulnerability # a weakness that a threat could exploit (unpatched software, weak password policy)
Risk # the likelihood a threat exploits a vulnerability, times the impact if it does
A vulnerability without a plausible threat isn't much of a risk — an unpatched service on an air-gapped machine with no network access is a much smaller risk than the same unpatched service exposed to the public internet. Risk is what lets you prioritize: you can't fix everything, so you fix what's both likely and costly first.
Risk = Likelihood x Impact
# A public-facing login form with no rate limiting:
# Likelihood: HIGH (automated credential-stuffing bots hit login forms constantly)
# Impact: HIGH (successful attack = full account takeover)
# -> Risk: HIGH. Fix this before almost anything else.
# An internal admin tool only reachable over VPN, running one version behind:
# Likelihood: LOW (requires VPN access first)
# Impact: MEDIUM (limited blast radius, internal only)
# -> Risk: LOW-MEDIUM. Patch it, but it's not this week's fire.
Security teams get flooded with findings from scanners, audits and bug bounties. The skill that actually matters is triage — this vocabulary is what lets you argue, in a standup, why one finding gets fixed today and another gets a ticket for next quarter.
3. STRIDE Threat Modeling
STRIDE is a checklist, originally from Microsoft, for systematically asking "what could go wrong here?" about a system. Each letter is a category of threat to check for at every trust boundary — anywhere data crosses from one level of trust to another (client to server, service to database, user to admin):
Spoofing # pretending to be someone/something you're not
Tampering # modifying data or code without authorization
Repudiation # denying you did something, with no way to prove otherwise
Information Disclosure # exposing data to someone who shouldn't see it
Denial of Service # making a system unavailable to legitimate users
Elevation of Privilege # gaining permissions you shouldn't have
Walk through a simple login flow with STRIDE and threats surface immediately:
Spoofing: Can an attacker submit someone else's username/password from a script?
-> Mitigation: rate limiting, CAPTCHA, MFA
Tampering: Can the login request be modified in transit (e.g. role=admin injected)?
-> Mitigation: TLS, server-side validation, never trust client-sent roles
Repudiation: If an account is compromised, is there a log of who logged in and when?
-> Mitigation: audit logging of authentication events
Info Disclosure: Does a failed login reveal whether the *username* exists?
-> Mitigation: identical error message for "wrong password" and "no such user"
Denial of Service: Can one IP lock out or overwhelm the login endpoint?
-> Mitigation: rate limiting, account lockout with backoff, WAF
Elevation of Priv: Can a regular user's session be reused to reach an admin-only endpoint?
-> Mitigation: server-side authorization checks on every request, not just at login
A read-only public dashboard with no login has little "Spoofing" or "Elevation of Privilege" surface, but plenty of "Denial of Service" surface. STRIDE is a prompt list to check systematically, not a form every box must be filled in on.
4. Data-Flow Diagrams & Attack Surface
Before you can threat-model a real system, you need to see it the way an attacker does: not as source code, but as data moving between components, crossing trust boundaries along the way. A data-flow diagram (DFD) is a simple sketch — boxes for processes and data stores, arrows for data flow, dashed lines for trust boundaries:
[Browser] --HTTPS--> | trust boundary | --> [Web Server] --> [Auth Service]
|
v
[Database]
# Trust boundaries here: Internet <-> Web Server, and Web Server <-> Database
# Each boundary is where you apply STRIDE: what can cross it that shouldn't,
# and what's protecting the crossing (TLS, authentication, network segmentation)?
The system's attack surface is everything an attacker could touch: every public endpoint, every input field, every third-party integration, every open port. Drawing the DFD first is what keeps a threat model from missing a whole component — you can't threat-model what you forgot was part of the system.
This same trust-boundary thinking reappears constantly: as the network zones you'll segment in Week 2, the container/host boundary in Week 9, and the cloud shared-responsibility line in Week 8. Get comfortable spotting trust boundaries now and every later week gets easier.
5. Hands-on Exercise
Threat-model a simple web app, then extend it with auth and a third-party integration
Apply the CIA triad, STRIDE and a DFD to a system you already understand: a basic note-taking app with a browser client, a web server, and a database — then grow it and see how the same process handles new complexity.
Part 1 — The base system:
- Draw a data-flow diagram (pen and paper or any tool) with three components: Browser, Web Server, Database, and mark every trust boundary between them.
- For each trust boundary, walk through all six STRIDE categories and write down at least one plausible threat — skip a category only if you can justify why it doesn't apply.
- For every threat you found, note which leg of the CIA triad it would break: confidentiality, integrity, or availability.
- Pick your top 3 threats and write a one-line risk estimate for each (likelihood × impact, informally) to decide which would get fixed first.
- Write one concrete mitigation per top-3 threat — a real control, not just "add more security."
Reuse the login-form STRIDE walkthrough above as a template — real threat models are built by applying the same checklist to a new diagram, not by inventing a new process each time.
Part 2 — Add authentication and a third-party integration:
Extend the same app with two realistic features: users must log in, and a "share note via email" button that calls a third-party email-sending API.
- Redraw the DFD with the new components, and identify exactly which new trust boundaries these two features introduce (browser ↔ auth check, server ↔ third-party email API) that Part 1's diagram didn't have.
- Run STRIDE specifically against these two new boundaries only — don't redo Part 1's work, focus on what's genuinely new. You should surface different threats than Part 1 did, since an auth flow and a third-party integration fail in different ways than a plain CRUD backend.
- For the third-party email API boundary specifically: what happens if that third party is compromised, or its response can't be fully trusted? What's the actual blast radius on your own system if you trust its response blindly?
- Revisit your Part 1 top-3 risk list — does anything from this new set of threats now outrank your original top 3? Update the list if so, and explain the reordering in one sentence.
If you're stuck on the third-party boundary, think about it the same way you'd think about a Spoofing threat on the login form — "what if the thing on the other side isn't actually who/what I expect it to be, or lies to me?" A third-party API you trust unconditionally is exactly that same shape of risk, just at a different boundary.
6. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
A DDoS attack that takes a checkout page offline mainly breaks which leg of the CIA triad?
A DDoS attack that takes a checkout page offline mainly breaks which leg of the CIA triad?
Availability. The data itself isn't stolen (confidentiality) or altered (integrity) — legitimate users simply can't reach the system, which is exactly what availability protects against.
Q2
What's the difference between a vulnerability and a risk?
What's the difference between a vulnerability and a risk?
A vulnerability is a weakness on its own (unpatched software, a weak password policy). Risk is that vulnerability combined with a plausible threat and its potential impact — likelihood × impact. The same vulnerability can be high risk when internet-facing and low risk when isolated on a private, air-gapped network.
Q3
In STRIDE, which category covers a login form that reveals whether a username exists via different error messages?
In STRIDE, which category covers a login form that reveals whether a username exists via different error messages?
Information Disclosure. Leaking whether an account exists lets an attacker enumerate valid usernames before attempting a credential-stuffing or brute-force attack — the fix is returning an identical error message regardless of which part of the login was wrong.
Q4
Why draw a data-flow diagram before threat-modeling a system?
Why draw a data-flow diagram before threat-modeling a system?
A DFD forces you to explicitly map every component and every trust boundary between them before checking for threats. Without it, it's easy to threat-model only the pieces you already had in mind and miss an entire component or integration — you can't apply STRIDE to a boundary you forgot existed.