Auth Security Best Practices for Indie SaaS
Everything a solo developer needs to know about authentication security — sessions, password hashing, rate limiting, and common pitfalls.
Authentication is the most security-critical part of any SaaS application. One mistake here and your users' data is exposed. Here's what you need to know as a solo founder shipping your own auth.
Password Hashing is Non-Negotiable
Never store plain text passwords. Never use MD5 or SHA for passwords. Use bcrypt, Argon2, or scrypt with a cost factor of 10-12.
// Good — bcrypt with cost factor 12
const hashed = await bcrypt.hash(password, 12);
// Bad — never do this
const hashed = sha256(password);Session Management
Use HttpOnly Cookies for Sessions
Store session tokens in HttpOnly, Secure, SameSite cookies. This prevents JavaScript from reading the token and blocks XSS attacks.
Set-Cookie: session_token=<token>; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=604800Rotate Sessions on Privilege Escalation
When a user logs in or changes their password, issue a new session token. This prevents session fixation attacks.
Set Reasonable Expiration
- Short-lived sessions: 7 days
- Remember me: 30 days max
- Force re-authentication for sensitive actions (password change, billing)
Rate Limit Your Auth Endpoints
Without rate limiting, attackers can brute force passwords. At minimum: 5 failed attempts → 15-minute lockout. 20 failed attempts → 1-hour lockout + email notification. Use IP-based and account-based rate limiting together.
Common Pitfalls
| Pitfall | Why It's Dangerous | Fix |
|---|---|---|
| Returning error on failed login | Tells attackers which emails exist | Return the same error for "user not found" and "wrong password" |
| Storing tokens in localStorage | Accessible to any XSS attack | Use HttpOnly cookies instead |
| No CSRF protection | Attacker can trigger actions on behalf of user | Use SameSite cookies + CSRF tokens |
| Logging passwords | Passwords end up in log files | Never log request bodies on auth routes |