Security Checklist
What we built
This checklist covers everything from both the auth course and this security course. Check each item before shipping.
Passwords
- Passwords are hashed with bcrypt (cost factor 10+)
- Plain-text passwords are never stored or logged
- Login returns the same error for “user not found” and “wrong password”
- Login timing is consistent (dummy hash for non-existent users)
Sessions
- Session IDs are random UUIDs (122 bits of entropy)
- Sessions have server-side expiry (24 hours)
-
deleteUserSessionsinvalidates all sessions for a user - Logout deletes the session and clears the cookie
Cookies
-
HttpOnlyset on session cookies -
Secureset in production (HTTPS only) -
SameSite=Laxset on session cookies -
Path=/for session cookies -
Max-Ageset (matches server-side session expiry)
Brute-force protection
- Per-IP rate limiting on login (20/minute)
- Per-email rate limiting on login (5/minute)
- Account lockout after 10 failed attempts (15-minute cooldown)
- Failed attempt counter clears on successful login
- Rate limiting on password reset requests
CSRF
-
SameSite=Laxon all auth cookies (baseline) - No state-changing GET routes
- CSRF tokens for cookie-based browser clients (if needed beyond SameSite)
- Token-based auth routes exempt from CSRF checks
Tokens (JWT)
- Access tokens expire in 15 minutes
- Refresh tokens stored server-side with family tracking
- Refresh token rotation on every use
- Reuse detection invalidates the token family
- Token deny list for immediate access token revocation
- JWT secret is at least 256 bits, randomly generated, stored in env
- Tokens are never returned in HTML pages or URLs
Password reset
- Reset tokens are hashed (SHA-256) before storage
- Reset tokens expire (1 hour)
- Reset tokens are single-use
- Forgot-password returns the same response for found and not-found emails
- All sessions invalidated after password reset
- Rate limiting on reset requests (3/hour per email)
Security headers
-
X-Content-Type-Options: nosniff -
X-Frame-Options: DENY -
Referrer-Policy: strict-origin-when-cross-origin -
Strict-Transport-Securityin production -
Content-Security-Policyin production (at minimumdefault-src 'self')
Logging
- Structured JSON logging
- Login success/failure logged with email and IP
- Rate limit hits logged
- Account lockouts logged
- Password resets logged
- Refresh token reuse logged
- Passwords, tokens, and session IDs never logged
Infrastructure (outside this course, but verify)
- HTTPS in production (TLS certificate)
- Environment variables for all secrets (not in source code)
-
.envin.gitignore - Dependencies audited (
npm audit) - Error responses do not expose stack traces
What we did not build
These are important security features that are beyond the scope of this course:
Two-factor authentication (2FA). TOTP codes (Google Authenticator, Authy) or WebAuthn (passkeys, hardware keys). This is the strongest protection against credential theft. A stolen password is useless without the second factor.
Email verification on signup. Confirming that the email address belongs to the user before creating the account. Similar to the password reset flow, but triggered at signup.
Dependency auditing. Running npm audit regularly to check for known vulnerabilities in your dependencies. A vulnerability in bcryptjs or jose could undermine everything.
Content Security Policy (advanced). We set a basic CSP. A production CSP would include nonces for inline scripts, specific CDN allowlists, and report-uri for violation monitoring.
DDoS protection. Application-level rate limiting does not stop a distributed denial-of-service attack. That requires infrastructure-level protection (Cloudflare, AWS Shield).
Input sanitization. Preventing SQL injection, XSS in templates, and other injection attacks. These are application-level concerns separate from auth.
Exercises
Exercise 1: Go through the checklist and check off everything your app implements. Identify any items you missed and add them.
Exercise 2: Pick one item from the “what we did not build” list and research how you would implement it. Write a brief plan (which routes, which functions, what data would you store).
Which security measure from this course has the widest impact (protects against the most attack types)?