Skip to content
DemoA made-up account, acme. Its deep scan of acme/api replays on a loop, sped up. Nothing here is real or saved.Back to the siteGet started
Agent Cernis
highhigh confidenceCWE-640authenticationOpen

Password reset links never expire and survive a password change

lib/auth/reset.ts:23

Impact

A password reset link found in an old email, a shared inbox or a proxy log still works months later, even after the user changed their password.

Attack path

2 steps
  1. Step 1: lib/auth/reset.ts:23Entry
    Tokens are stored without an expiry and never invalidated on use.
    22await db.resetTokens.insert({ userId, token: hash(token) });
  2. Step 2: app/reset/[token]/page.tsx:12Sink
    Lookup checks existence only.
    11const row = await db.resetTokens.find({ token: hash(params.token) });

Fix

Store an expiry (30 minutes is typical), delete the token on use, and delete all of a user's tokens when their password changes.