Injection, XSS, CSRF & Auth Fundamentals
SQL Injection
// BAD — user input concatenated directly into the query
db.query(`SELECT * FROM users WHERE email = '${email}'`);
// GOOD — parameterized, input never touches the query structure
db.query('SELECT * FROM users WHERE email = $1', [email]);XSS & CSRF
XSS: unsanitized user content rendered as HTML lets an attacker's script run in another user's browser — escape/encode output (React/Vue/Angular do this by default). CSRF: a victim's already-authenticated browser is tricked into submitting a request to a target site — defend with unpredictable CSRF tokens on state-changing requests, plus the SameSite cookie attribute.
Password Storage
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(plainPassword, 12); // salting handled automatically
const valid = await bcrypt.compare(plainPassword, hash);
// bcrypt/Argon2, never plain SHA-256/MD5 — deliberately slow, defeats brute forceSalting ensures identical passwords produce different hashes, defeating precomputed rainbow-table attacks. Modern libraries (bcrypt, Argon2) handle salting internally.
Authentication vs. Authorization
Authentication = who you are. Authorization = what you're allowed to do. A user can be correctly authenticated yet still unauthorized for a specific resource — confusing the two is a common real bug class (see IDOR below).
Insecure Direct Object References (IDOR)
/orders/12345 without verifying the logged-in user actually owns order 12345 — an attacker just changes the ID to view someone else's data, no authentication bypass needed. Always check authorization per-object, not just per-endpoint.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free