Get a Pentest and security assessment of your IT network.

Cyber Security

Passwordless Reset Options

TL;DR

Single-use password reset links are convenient but have security weaknesses (phishing, link expiry issues). Better options include magic links sent to a registered email address, one-time passcodes (OTP) via SMS or authenticator apps, and WebAuthn/Passkeys. This guide explains how to implement these alternatives.

1. Understand the Risks of Password Reset Links

Password reset links are often targeted by attackers because:

  • Phishing: Attackers can create fake emails that look legitimate, tricking users into clicking malicious links.
  • Link Expiry: Short expiry times improve security but cause user frustration if they don’t reset immediately. Longer expiry times increase risk.
  • Replay Attacks: If a link is intercepted, it can be used even after the user intended to discard it.

2. Magic Links (Email-Based)

Magic links send a temporary login link directly to the user’s registered email address. This avoids passwords altogether for reset.

  1. Generate a Unique Token: When a user requests a reset, create a cryptographically secure random token (e.g., using UUID).
  2. Store Token & User Association: Store the token linked to the user’s account in your database with an expiry timestamp (e.g., 15 minutes).
  3. Send Email with Link: Send an email containing a link like https://yourdomain.com/reset?token=[unique_token].
  4. Verify Token on Reset Request: When the user clicks the link, verify the token exists, hasn’t expired, and matches the requesting user.
  5. Allow Password Change: If valid, allow the user to set a new password. Immediately invalidate the token after use.

Example (Python with Flask):

from uuid import uuid4
import datetime
# ... database code omitted for brevity...

def generate_reset_token():
    return str(uuid4())

def send_magic_link(email, token):
    # Send email with link: https://yourdomain.com/reset?token=token
    pass # Replace with your email sending logic

3. One-Time Passcodes (OTP)

OTP sends a temporary code to the user via SMS or an authenticator app.

  1. Generate OTP: Create a 6-8 digit random number.
  2. Send OTP: Send the OTP to the user’s registered phone number (SMS) or through their authenticator app.
  3. Verify OTP on Reset Request: When the user enters the code, verify it matches the one you sent and hasn’t expired (e.g., 5 minutes).
  4. Allow Password Change: If valid, allow password reset.

Important Considerations for SMS OTP:

  • SMS is less secure than authenticator apps due to SIM swapping attacks.
  • Use a reliable SMS gateway provider.

4. WebAuthn/Passkeys

WebAuthn (and its related Passkey standard) allows users to use biometric authentication or hardware security keys for passwordless login and reset.

  1. User Registration: The user registers a WebAuthn credential (e.g., fingerprint, face ID, security key).
  2. Reset Request: When requesting a reset, the system prompts the user to authenticate using their registered WebAuthn credential.
  3. Authentication & Password Change: If authentication succeeds, allow password reset without requiring a traditional password or OTP.

Benefits of WebAuthn/Passkeys:

  • Highly secure – resistant to phishing and many other attacks.
  • User-friendly experience.

Resources: Explore libraries like webauthn in Python or the Mozilla WebAuthn documentation.

5. Security Best Practices (For All Methods)

  • Rate Limiting: Limit the number of reset requests from a single IP address or user account to prevent brute-force attacks.
  • Account Lockout: Temporarily lock accounts after multiple failed reset attempts.
  • Token/OTP Storage Security: Protect tokens and OTPs in your database using strong encryption.
  • HTTPS Only: Always use HTTPS to encrypt communication between the user and your server.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation