Back to blog

Password Reset Best Practices for 2026

ResetKit Team··8 min read
securitybest practicesauthentication

Password reset is one of the most critical, and most attacked, parts of any authentication system. Get it wrong, and you've opened a backdoor into user accounts. Get it right, and you've built trust with your users.

Here's what we've learned building password reset infrastructure at scale.

1. Never Trust Email Alone

Email-only password reset is vulnerable to account takeover if someone gains access to a user's inbox. Add a second factor:

  • Email + SMS code: Send a 6-digit code to their phone number
  • Email + Security questions: Not recommended (weak security)
  • Email + Time-based lockout: Require users to wait 24 hours before completing reset

The best approach depends on your threat model. For most apps, email + SMS provides the right balance of security and UX.

2. Rate Limit Everything

Attackers will try to:

  • Enumerate your user database by requesting resets for every email
  • Brute force verification codes
  • Spam users with reset requests

Implement rate limiting at multiple layers:

// Per email: 3 requests per hour
// Per IP: 10 requests per hour  
// Per account: Lock after 5 failed verification attempts

This prevents abuse while allowing legitimate users to retry if needed.

3. Use Short-Lived Tokens

Reset tokens should expire quickly. We recommend:

  • 15 minutes for password reset links
  • 5 minutes for 2FA codes
  • 30 minutes for magic links

Shorter windows reduce the attack surface. If a user's email is compromised, the attacker has less time to act.

4. Hash Everything

Never store verification codes in plaintext. Use bcrypt with appropriate rounds:

  • Passwords: 12 rounds (slow, high security)
  • Verification codes: 10 rounds (fast enough for real-time verification)

This protects users even if your database is breached.

5. Prevent Enumeration

Don't reveal whether an email exists in your system. Always return:

{
  "success": true,
  "message": "If that email exists, we sent a reset link."
}

Use timing-safe comparisons and add dummy operations to ensure response times are identical for existing/non-existing emails.

6. Log Everything

Audit logs are critical for:

  • Detecting abuse patterns
  • Investigating security incidents
  • Compliance (GDPR, SOC 2)

Log: email (hashed), timestamp, IP, success/failure, session ID. Never log plaintext passwords or codes.

Conclusion

Password reset is deceptively complex. Most teams underestimate the security considerations and end up with vulnerable implementations.

That's why we built ResetKit, to handle all of this for you. Our infrastructure includes rate limiting, enumeration protection, bcrypt hashing, and audit logging out of the box.

Want to see it in action? Start a free trial and integrate in 15 minutes.

Ready to integrate?

Add password reset and 2FA to your app in about fifteen minutes. Free right now.

Start for free