Predictable password reset tokens

Predictable password reset tokens

Description

Generating password reset tokens from predictable values such as uniqid, rand or mt_rand may let an attacker guess a reset link or code. Reset tokens must use cryptographically secure randomness with sufficient entropy.

Potential impact

  • Guessing password reset links
  • Account compromise
  • A greater chance of successfully guessing reset codes

Remediation

  • Generate tokens using cryptographically secure randomness, such as bin2hex(random_bytes(32)).
  • Store token hashes, set a short expiry and allow each token to be used only once.
  • Obtain the reset-link domain from trusted configuration, not the request’s Host header.

Examples

savePasswordResetToken() is an omitted application function that stores each user’s token hash and expiry. The reset handler must verify the hash and expiry, then prevent reuse of a consumed token.

Before

php
<?php
$resetToken = uniqid();
mail($email, 'Password reset', 'Use token ' . $resetToken);

After

php
<?php
$resetToken = bin2hex(random_bytes(32));
$tokenHash = hash('sha256', $resetToken);
savePasswordResetToken($userId, $tokenHash, time() + 900);
mail($email, 'Password reset', 'Use token ' . $resetToken);

Explanation:

  • Before: Uses a predictable value for a password reset token, allowing an attacker to guess a reset link or code.
  • After: Generates a cryptographically random reset token and stores its hash with a short expiry on the server.

References