Basic

The standing checklist

I fixed one hole and missed the next. Security is a checklist you run on every endpoint, so no single fix is the whole story.

What you will see

route /change POST, no token -> fails CSRF line

About 1 min of reading

Try It

Audit one route against the checklist.

1

A route that sets innerHTML from user input fails the escape line. That is the hole.

print('route /search sets innerHTML from q -> fails escape line')

Before you run it, say out loud what it will print. Then open the answer.

What it prints
route /search sets innerHTML from q -> fails escape line
2

A state-changing POST with no CSRF token fails the CSRF line. Add the token.

print('route /change POST, no token -> fails CSRF line')

Before you run it, say out loud what it will print. Then open the answer.

What it prints
route /change POST, no token -> fails CSRF line

Data Flow

Security is a checklist applied to every route: hash, secrets, escape, CSRF, constant-time, plus response headers; a hole is a route that skipped one line.
1 Walk each route
↓
2 Ask each checklist line
↓
3 Skipped line is the hole
↓
4 Headers cover every page
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

print('route /search sets innerHTML from q -> fails escape line') route /search sets innerHTML from q -> fails escape line
Why this works
Audit per route

Security is not one switch, it is a list applied to every entry point. Walk each route and ask: does it escape input, require a CSRF token, compare secrets in constant time, hash passwords slowly? A route that skipped a line is the hole.

Headers close the browser gaps

Response headers (CSP, X-Frame-Options, HSTS) close holes the browser would otherwise allow. They are part of the same checklist, applied at the response, not the handler. Add them once and they cover every page.

Examples

The list

1 hash passwords slow + salted
2 secrets from env, rotated
3 escape all user text
4 CSRF token on changes
5 constant-time secret compare

Run it per route

for route in app.routes:
    audit(route)   # does it escape? check csrf? hash?

Audit each route against the list. A hole is a route that skipped one line, not a missing idea.

Add headers

Content-Security-Policy
X-Frame-Options

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Comparing without leaking
Previous Lesson
Comparing without leaking
Next Lesson
The wire is not safe
The wire is not safe →