Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Email OTP login has no attempt limit: useVerificationToken doesn't invalidate the code on a wrong guess (brute-forceable account takeover)

Aperta
#2,221 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
nextjs, typescript

Direzione di ricerca

Inizia in packages/database/auth/drizzle-adapter.ts, in useVerificationToken, quindi confronta la gestione delle discrepanze con apps/web/app/api/mobile/[...route]/route.ts:543-548. Esamina il punto di ingresso del callback e-mail e i controlli auth esistenti prima di convalidare il comportamento. Il lavoro è completato quando un codice errato invalida la riga di verifica e non può essere ritentato, mentre la verifica corretta continua a funzionare.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug
Summary

useVerificationToken in packages/database/auth/drizzle-adapter.ts (lines 512-538) only
deletes the verification row on a successful match. A wrong 6-digit code guess finds no row
(lookup is by exact token value), logs a warning, and returns null the real code is left
untouched. It can be guessed without limit for its entire TTL (10 minutes as of #2068).

This is a logic bug, not just a missing rate limit: the mobile login path already does this
correctly. apps/web/app/api/mobile/[...route]/route.ts:543-548 deletes the row on a token
mismatch before returning "invalid", burning the code on the first wrong attempt. The web
(NextAuth) path has no equivalent.

Repro
  1. POST /api/auth/signin/email for a target address.
  2. Fire guesses at GET /api/auth/callback/email?email=<target>&token=<6-digit>.
  3. Codes come from crypto.randomInt(100000, 1000000) (900,000 possible values,
    auth-options.ts:138). At ~100 req/s, ~6.7% success chance within the 10-minute window;
    sustained guessing lands a hit in a few hours.
Why this isn't closed by existing rate-limit ids

RATE_LIMIT_IDS.AUTH_OTP_VERIFY / AUTH_OTP_SEND (apps/web/lib/rate-limit.ts:83-85) are
declared but have zero call sites (see #2039, PR #1924 open and stale since June, PR #2040
closed without wiring these two). Even once wired, isRateLimited is backed by Vercel Firewall
and fails open without a matching dashboard rule, so it provides no protection on self-hosted
deployments
regardless. The durable, hosting-agnostic fix has to live in
useVerificationToken itself.

Suggested fix

Delete (or otherwise invalidate) the verification row on a failed match too, not only on
success mirroring the mobile implementation. Wiring AUTH_OTP_VERIFY/AUTH_OTP_SEND as
defense-in-depth on Vercel deployments is worth doing separately, but shouldn't be treated as
the fix on its own since it doesn't cover self-hosted instances.

Related
  • #2039 (open), broader unwired-rate-limit-ids issue, includes these two ids but not this root cause
  • #1924 (open, stale), Firewall-based rate limiting, never merged
  • #2068 (merged), fixed the 24h→10min window, explicitly left the attempt-counter fix as follow-up
  • #2040 (closed), deliberately punted on wiring these two ids
Lingua principale
Rust
Stelle
22.8k
Fork
2k
Merge medio
8h 10m
PR unite (30g)
83

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di CapSoftware/Cap

Tutte le issue di CapSoftware/Cap

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.