Lesson 6 of 7 · 14 min · 2 hands-on steps
Authentication & Web Security Basics
How logins really work, and the attacks every developer must defend against.
How logins actually work
- You send your email and password over HTTPS (encrypted)
- The server hashes the password and compares it with the stored hash. Passwords are never stored in plain text.
- If it matches, the server creates a random session token, stores it, and sends it back in a cookie marked
HttpOnlyandSecure - Your browser sends that cookie with every request, so the server knows it's you
// Hashing is one-way: you can check a password, but you can't reverse the hash.
async function sha256(text) {
const bytes = new TextEncoder().encode(text);
const hash = await crypto.subtle.digest("SHA-256", bytes);
return [...new Uint8Array(hash)].map((b) => b.toString(16).padStart(2, "0")).join("");
}
console.log(await sha256("hunter2"));(Real password storage uses a deliberately slow hash with a random salt, like bcrypt or PBKDF2, so attackers can't guess billions of passwords per second. This site uses PBKDF2.)
Authentication vs authorization
- Authentication: who are you? (logging in)
- Authorization: what are you allowed to do? (can this user delete this post?)
Always check authorization on the server for every action. Hiding a button in the UI isn't security.
The attacks you must know (OWASP Top 10 highlights)
| Attack | What happens | Defense |
|---|---|---|
| XSS | Attacker's script runs on your page | Escape output; use textContent; frameworks escape by default |
| SQL injection | Input changes your SQL query | Always use parameterized queries |
| CSRF | Another site submits forms as your user | SameSite cookies, origin checks |
| Broken access control | Users reach data that isn't theirs | Check ownership on every request |
| Leaked secrets | API keys in code or Git | Environment variables / secret managers |
// ❌ SQL injection: never build queries from strings
const name = "x' OR '1'='1";
console.log(`SELECT * FROM users WHERE name = '${name}'`);
// ✅ parameterized: db.prepare("SELECT * FROM users WHERE name = ?").bind(name)Security questions come up in interviews for every web role. Knowing these five puts you ahead of most junior candidates.
🧪 Practice: 2 steps
0 / 2 doneStep 1 of 2 · Escape HTML (stop XSS)
Write escapeHtml(text) that replaces the five dangerous characters so user text can never become HTML:
& → &, < → <, > → >, " → ", ' → '
function escapeHtml(text) {
return text;
}
Output appears here. Press Run or Ctrl/⌘ + Enter.
Step 2 of 2 · Who can do what?
Write authorize(user, action, post) that returns true if allowed:
- not logged in (
userisnull): can only"read" - logged-in users: can
"read"and"comment" - can
"edit"or"delete"a post only if they wrote it (post.authorId === user.id) or they're an admin (user.role === "admin")
function authorize(user, action, post) {
return false;
}
Output appears here. Press Run or Ctrl/⌘ + Enter.
✅ Check your understanding
How should passwords be stored?
Authentication vs authorization?
Create a free account to track your progress.