Authentication and Web Security
Authentication vs authorization
- Authentication: who are you? (login)
- Authorization: what are you allowed to do? (permissions)
Passwords
Never store plain text or fast hashes. Use a slow, salted algorithm.
const bcrypt = require("bcrypt");
async function register(email, password) {
const hash = await bcrypt.hash(password, 12); // salted, work factor 12
// store { email, hash }
}
async function login(email, password, user) {
return bcrypt.compare(password, user.hash); // true / false
}
Sessions vs JWT
| Server sessions | JWT (stateless token) | |
|---|---|---|
| State | Stored on the server | In the token |
| Revocation | Easy (delete session) | Hard until expiry |
| Scaling | Needs shared store (Redis) | Easy |
| Best for | Browser apps | APIs, service-to-service |
For browser apps, prefer an HttpOnly, Secure, SameSite session cookie.
res.cookie("sid", sessionId, {
httpOnly: true, // not readable from JavaScript
secure: true, // HTTPS only
sameSite: "lax", // mitigates CSRF
maxAge: 1000 * 60 * 60 * 24,
});
OWASP-style threats
| Threat | What happens | Defence |
|---|---|---|
| XSS | Attacker script runs in your page | Escape output, avoid innerHTML, CSP |
| CSRF | A site triggers actions with the user's cookies | SameSite cookies, CSRF tokens |
| SQL injection | Input becomes SQL | Parameterised queries |
| Broken access control | Users read others' data | Check ownership on every request |
| Sensitive data exposure | Secrets or PII leak | TLS, env vars, least privilege |
| Brute force | Password guessing | Rate limiting, lockouts, MFA |
Authorization check example
app.get("/api/notes/:id", requireAuth, async (req, res) => {
const note = await getNote(req.params.id);
if (!note) return res.status(404).end();
if (note.userId !== req.user.id) return res.status(403).end(); // ownership check
res.json(note);
});
Checklist
- HTTPS everywhere; HSTS enabled
- Passwords hashed with bcrypt/argon2
- Secrets in environment variables, never in the repository
- Input validated and output encoded
- Security headers (
helmet) and a Content-Security-Policy - Dependencies audited (
npm audit) and updated
Loading Comments...