What are you defending?

Decide what you are protecting and from whom, so the rest of this course is a list of decisions rather than a list of fears.

01of 16
≈ 11Min read
6Parts

Security is not a feature you add

There is no amount of hardening that makes an application "secure". There is a set of things worth protecting, a set of people who might want them, and a set of ways in. A threat model is the half-hour where you write those three lists down — and it is the difference between spending a week on the thing that matters and a week on the thing that was easiest to read about.

The four questions

  • What are we building? A drawing of the pieces: the browser, your server, the database, the payment provider, the email service. Every arrow between two boxes is a place data crosses a boundary.
  • What can go wrong? For each box and arrow: what would an attacker do? Read something they should not, change something, pretend to be somebody, stop it working, or get in and stay in.
  • What are we going to do about it? Per risk: fix it, reduce it, accept it, or move it to someone who does it better (a payment provider, an identity provider).
  • Did we do a good job? Write it down, re-read it when the architecture changes, and keep the "accepted" list honest.

Assets, and being specific

"Protect user data" is not a plan. "An attacker with a stolen session cookie can read another customer's order history through /api/orders/:id" is a plan, because it names the fix.

AssetWhat "compromised" meansWorth
Customer recordsnames, addresses, order history leakreputation, a regulator, every customer
Session cookiesan attacker acts as a useranything that user can do
The admin panelan attacker acts as youeverything
The API key for the mail servicephishing from your domainyour domain’s reputation
Uptimethe shop is closedrevenue per hour

Trust boundaries

everything crossing a line is untrusted, in both directions
browser  ──►  your server      every field, header, cookie and URL is attacker-controlled
server   ──►  database         everything must be parameterised
server   ──►  another API      their response can be hostile too
server   ──►  browser          everything you send back is escaped for where it lands
browser  ──►  browser          another site's page can make requests to yours
The client is not a boundary you control

Validation in the browser is a courtesy to the user. Every check that matters happens on the server, because the request can be made without your page: curl, a replayed request, a modified app. Anything else is the same mistake wearing a different hat.

Who is actually attacking you

Almost every real incident at a small company comes from the first two rows: a known vulnerability in an old dependency, an exposed admin route, a leaked key in a repository, a password reused from another breach. The exotic attacks are real and they are not your first problem.

WhoWantsEffort they will spend
Automated scannersanything at all, at scaleseconds — they find the default admin password
An opportunistyour data, your compute, your domainhours, if it looks easy
A competitor or a scraperyour catalogue, your pricesdays, and they will read your API
An angry insiderspecific damagethey already have credentials
A targeted attackeryou specificallyas long as it takes

Defence in depth, and failing safely

One control will eventually fail, so the question is what happens next. Escaping stops XSS; CSP limits what an escape you missed can do. A parameterised query stops injection; a database user with read-only access limits what a missed one reaches. A session cookie is HttpOnly; it is also short-lived and bound to a device.

And when something fails, it should fail closed: an error in the permission check means no access, not access. A surprising number of breaches are a try/catch that swallowed the check and carried on.

Practice