mediumCWE-287A07:2021

Insecure Remember Me Token

Persistent 'remember me' tokens that are predictable, non-expiring, or stored insecurely — allowing attackers to forge tokens or maintain access indefinitely after compromise.

How It Works

Remember-me tokens are long-lived credentials stored in cookies. If the token is derived from predictable data (user ID + timestamp), an attacker can forge valid tokens. If tokens never expire or aren't rotated on use, a single stolen token grants permanent access. Proper implementation requires cryptographic randomness and one-time-use token rotation.

Vulnerable Code
// BAD: predictable token based on user data
function generateRememberToken(userId: string): string {
  return Buffer.from(`${userId}:${Date.now()}`).toString('base64');
  // Predictable! Attacker can compute valid tokens
}
Secure Code
// GOOD: cryptographically random, stored hashed, rotated on use
import { randomBytes, createHash } from 'crypto';
async function generateRememberToken(userId: string) {
  const token = randomBytes(32).toString('hex');
  const hash = createHash('sha256').update(token).digest('hex');
  await db.rememberTokens.create({
    data: { userId, tokenHash: hash, expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000) }
  });
  return token; // send this to the client
}

Real-World Example

Early PHP apps with predictable remember-me tokens (md5(user_id + static_secret)) were widely exploited. If an attacker knows your user IDs (often sequential integers), they can forge remember-me cookies for any account.

How to Prevent It

  • Use cryptographically random tokens (crypto.randomBytes(32) minimum)
  • Store only the hash of the token in the database, not the raw token
  • Set a reasonable expiry (30 days max) and rotate the token on each use
  • Invalidate all remember-me tokens on password change or when suspicious activity is detected

Affected Technologies

nodejsNext.jsPythonPHP

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities