Appearance
8.1 — The Security Mindset
A checkout endpoint takes a price from the request body, because the frontend already knows it.
ts
app.post('/checkout', async (req, res) => {
const { sku, priceMinor, qty } = req.body; // (1)
await charge(req.user, priceMinor * qty); // (2)
});(1) The price arrives from the browser. (2) It is charged without ever being compared to the catalogue.
Every developer who reads this sees a working checkout. The security mindset is the habit of reading the same code and asking a different question: what happens if the caller does not behave the way I imagined? Send priceMinor: 1 and buy a laptop for a penny. Send qty: -1 and get a refund.
That is the whole discipline in one example. It is not a body of arcane knowledge; it is a systematic way of asking what else is possible here, applied before an attacker asks it for you.
1. The three questions
Who might want to attack this, and what would they gain? A hobbyist defacing a page, an opportunist running automated scanners against every host on the internet, a competitor, an insider, an organised criminal group after money, or a state actor after data. They differ in patience and budget, not in cleverness. Your defences should be sized against the ones who will actually show up: for almost every system, that is automated scanners and opportunists, and designing against a nation state while leaving default credentials on an admin panel is the common failure.
What am I protecting, and what happens if it is lost? Not "the database" — specific things. Customer personal data, payment credentials, the ability to move money, the ability to run code on your servers, your reputation, availability during a sale. Each has a different loss.
Where are the boundaries? Every place data crosses from something you control to something you do not is a trust boundary, and every one is where validation must happen.
2. The CIA triad, and the two people add
Confidentiality — only the right people can read it. Broken by a data leak.
Integrity — data is not altered without authorisation. Broken by a tampered price, a forged token, a modified log.
Availability — the system is usable when needed. Broken by a denial-of-service attack, a ransomware encryption, or an outage.
These conflict, and knowing that is the useful part. Encrypting backups helps confidentiality and hurts availability if the key is lost. Aggressive rate limiting protects availability and blocks real users. Detailed audit logs help integrity investigations and create a confidentiality problem of their own. Security work is choosing where on those trade-offs to sit, not maximising all three.
Two more are usually added:
Authenticity — the message really came from who it claims. Signatures, in Chapter 8.2.3.
Non-repudiation — they cannot credibly deny having done it. Signed audit records.
3. Threat modelling, done in an hour
Threat modelling has a reputation for being a heavyweight process with diagrams nobody reads. The useful version fits in a meeting, and it is the single highest-value security activity available to a normal team.
Step 1 — draw the system, with the data stores, the processes, the external entities and, most importantly, a line around what you control.
Step 2 — mark the trust boundaries. Browser to server. Service to service. Your code to a third-party API. Application to database. Anything crossing a line needs validation on the receiving side.
Step 3 — walk each element with STRIDE, which is a prompt list rather than a theory:
| Letter | Threat | Defends with |
|---|---|---|
| S | Spoofing an identity | Authentication |
| T | Tampering with data | Integrity checks, signatures |
| R | Repudiation | Audit logs |
| I | Information disclosure | Encryption, access control |
| D | Denial of service | Rate limits, quotas, timeouts |
| E | Elevation of privilege | Authorisation, least privilege |
For each element, ask each letter. Most answers are "not applicable" in seconds; the ones that stick are your real risks.
Step 4 — rank by likelihood × impact and fix the top few. A threat model that produces forty items and no decisions has failed. Three items with owners and dates is a success.
Step 5 — revisit when the architecture changes, not on a calendar.
The most common finding is not exotic. It is an endpoint nobody realised was reachable without authentication, or an internal service that trusts anything on the network, or an admin interface with no second factor.
4. The principles that actually decide designs
Least privilege. Every component gets the minimum access it needs. The reporting service reads; it does not need DELETE. The web server needs no credentials for the payments database. The test: if this component were fully compromised, what could the attacker reach? That answer is the blast radius, and least privilege is the tool for shrinking it.
Defence in depth. Assume any one control will fail, because eventually one will. A parameterised query stops injection; a database user with read-only access limits what injection achieves; monitoring notices the unusual query volume; encrypted columns limit what the dump is worth. No single layer has to be perfect.
Fail closed. When something goes wrong, deny. If the authorisation service is unreachable, refuse rather than allow. The exception is availability-critical paths where you have made a written decision to fail open — a rate limiter is the usual example (Chapter 9.7.5) — and that decision should be explicit rather than an accident of a catch block.
Secure by default. The safe configuration is what you get without doing anything. New buckets are private. New users have no permissions. TLS is on. Every security feature that must be turned on will be off somewhere.
Minimise the attack surface. Every endpoint, port, dependency, feature flag and admin panel is something to defend. Deleting an unused feature is a security improvement, and it is the cheapest one available.
Do not roll your own cryptography. Chapter 8.2 explains why in detail. The short version: the failures are invisible — your broken implementation encrypts and decrypts correctly and is still breakable.
Complete mediation. Check authorisation on every access, not once at the start of a session. The classic violation is checking permissions when rendering a menu and not when handling the request the menu links to.
Open design. Security must not depend on the design being secret. Assume the attacker has read your source code — many can, and any employee could. A secret key is a secret; an algorithm is not.
Psychological acceptability. A control people route around provides nothing. Password rules that force quarterly rotation produce Summer2026! and a sticky note. If your security makes the job impossible, the job wins.
5. Vulnerability, threat, risk — used precisely
These three words are used interchangeably in conversation and mean different things in an incident report.
A vulnerability is a weakness. Unpatched software, a missing authorisation check.
A threat is an actor or event that could exploit it. An automated scanner, a disgruntled insider.
Risk is likelihood × impact. A vulnerability with no plausible threat, or with trivial impact, is low risk. This is what lets you order work honestly rather than treating every scanner finding as an emergency.
An exploit is the working attack; a zero-day is a vulnerability with no available patch — dangerous mainly because the defence has to be something other than updating.
CVE is the public identifier (CVE-2021-44228 is Log4Shell), and CVSS is a 0–10 severity score. Treat CVSS as an input, not an answer: a 9.8 in a library your code never calls may be irrelevant, and a 5.3 on your internet-facing login page may be urgent. Exploitability in your deployment is the number that matters, which is why exploit-prediction data and reachability analysis have become the practical filters.
6. The attacker's actual workflow
Defences make more sense once you know the sequence, and it is remarkably consistent.
Reconnaissance — public information. Subdomains from certificate transparency logs (every TLS certificate you have ever issued is public, which surprises people), employee names from professional networks, technology stacks from response headers, code and credentials from public repositories.
Scanning — automated probing for known vulnerable versions, open ports, default paths (/admin, /.env, /.git/config, /actuator). This happens to every host on the internet within minutes of it existing. A new server receives scanner traffic before you have finished configuring it.
Initial access — a known vulnerability, stolen credentials from an unrelated breach, or a phishing email. Phishing and credential reuse dominate, which is why multi-factor authentication (Chapter 8.4.7) is worth more than most technical hardening.
Lateral movement — from the machine they landed on to the ones they wanted. This is where flat networks and shared credentials turn a small compromise into a large one, and where least privilege pays.
Persistence — a way back in: a new account, a scheduled task, a key added to an authorised-keys file.
Exfiltration or action — copying data out, encrypting for ransom, or transacting.
Two conclusions follow directly. Preventing initial access is necessary and not sufficient — plan for the attacker being inside, which is the whole argument for segmentation, least privilege and monitoring. And detection matters as much as prevention: the industry statistic that keeps repeating is that intrusions go undetected for weeks or months, which is enough time to take everything.
7. What to actually do, in order
For a normal engineering team, ordered by value per hour spent:
- Multi-factor authentication everywhere, especially on cloud consoles, source control and email. Most real compromises start with a password.
- Patch dependencies automatically. Known vulnerabilities in outdated libraries are the most exploited category, and the fix is a scheduled bot rather than a person remembering.
- Secrets out of source control, with rotation. Chapter 8.6.1 covers how; a leaked key in a public repository is found by automated scanners in minutes.
- Least privilege on cloud roles and database users. The most common excessive permission is the one granted while debugging and never removed.
- Encrypt in transit everywhere — including inside your network. Chapter 5.7.
- Log authentication events, authorisation failures and admin actions, centrally, where an attacker on the compromised host cannot edit them.
- Have an incident plan. Who is called, how systems are isolated, who talks to customers, where the backups are and whether a restore has ever been tested. An untested backup is a hope.
- Then application-level hardening — Chapter 8.5.
The ordering is the point. Teams routinely spend a week on a content security policy while their cloud administrator account has no second factor.
8. Two ideas worth understanding before Chapter 8.5
Zero trust means the network location grants no privilege. Being inside the corporate network or the VPC proves nothing; every request is authenticated and authorised on its own. This replaces the older model where a hard perimeter surrounded a soft, fully trusting interior — a model that fails the moment one machine inside is compromised, which is the entire lateral-movement step above.
The confused deputy is the shape behind a surprising number of vulnerabilities. A component with more privilege than the caller is tricked into using that privilege on the caller's behalf. Your server can reach the internal metadata service and the user cannot, so the user asks your server to fetch a URL — that is SSRF. Your browser holds the user's session cookie and attaches it automatically, so an attacker's page makes it send a request — that is CSRF. Both are the same idea, and recognising the shape means recognising the next instance of it before it has a name.
What the interviewer will push on
"How would you approach securing a new service?" Threat model first: draw it, mark the trust boundaries, walk STRIDE, rank by likelihood times impact, fix the top few. Then the practical ordering — MFA, dependency patching, secrets management, least privilege — before application-level hardening. Starting with "add a WAF" or "set security headers" is the answer of someone who has read a checklist.
"What is least privilege and how do you test whether you have it?" Minimum access per component, tested by asking what an attacker could reach if this component were fully compromised. That question turns a principle into a concrete blast-radius answer, which is what the interviewer is listening for.
"Explain defence in depth with a real example." Injection: parameterised queries stop it, a read-only database user limits what it achieves, monitoring catches the unusual query pattern, and column encryption limits the value of the dump. Each layer assumes the one above it failed.
"What is the difference between a vulnerability, a threat and a risk?" Weakness, actor who could exploit it, likelihood times impact. Then apply it: a CVSS 9.8 in code you never call may be low risk, and a 5.3 on your login page may be urgent, so exploitability in your deployment is what orders the work.
"What is zero trust?" Network location grants no privilege — every request authenticated and authorised regardless of where it came from. The tell is naming what it replaces and why: a hard perimeter with a trusting interior fails at the lateral-movement step, which is exactly what real intrusions do.
"An engineer says a bug isn't exploitable. How do you respond?" Ask what specifically prevents it, whether that control could ever be absent (a new endpoint, a different client, an internal caller), and what the impact would be if the assumption were wrong. Then decide by risk rather than by confidence. "Not exploitable" is a claim about today's code, not about the code after the next change.
One thing to volunteer: point out that every TLS certificate you issue appears in public certificate transparency logs, so internal hostnames like staging-admin.example.com are published to the world the moment you get a certificate. It is a reconnaissance detail almost nobody accounts for, and it argues for wildcard certificates or a private CA for internal names.
Recall
- The mindset is one habit: read working code and ask what else the caller could send. A price taken from the request body is a working checkout and a free laptop.
- Confidentiality, Integrity, Availability conflict on purpose — encryption versus recoverability, rate limits versus real users. Security is choosing where to sit, not maximising all three.
- Threat modelling that works: draw it, mark trust boundaries, walk STRIDE per element, rank by likelihood × impact, fix three things with owners. Forty findings and no decisions is a failed model.
- Principles that decide designs: least privilege (tested by "what if this were fully compromised"), defence in depth, fail closed, secure by default, minimise attack surface, complete mediation (check on every access, not once per session), open design, and psychological acceptability — a control people route around provides nothing.
- Vulnerability (weakness) × threat (actor) = risk (likelihood × impact). CVSS is an input, not an answer — exploitability in your deployment orders the work.
- The attack chain is recon → scan → initial access → lateral movement → persistence → exfiltration. Phishing and credential reuse dominate initial access, so MFA outranks most technical hardening, and segmentation plus detection matter because you must assume they get in.
- Priority order: MFA → automatic dependency patching → secrets out of source control → least privilege → TLS everywhere → central auth logging → a tested incident plan → then application hardening.
- Zero trust = network location grants no privilege. The confused deputy — a privileged component tricked into acting for a caller — is the same shape behind both SSRF and CSRF.
Self-test: What question turns a principle like least privilege into a concrete answer? · Name two CIA controls that conflict · What makes a threat model succeed rather than produce a list? · Why can a CVSS 9.8 be lower priority than a 5.3? · Which step of the attack chain does MFA target, and which does segmentation target? · What do SSRF and CSRF have in common?
Next: 8.2.1 starts the cryptography properly — what symmetric encryption actually does, why the mode matters more than the cipher, and why a nonce reused once can destroy everything.