Email OTP login has no attempt limit: useVerificationToken doesn't invalidate the code on a wrong guess (brute-forceable account takeover)
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
- Ambito
- api, authentication, database
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
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
POST /api/auth/signin/emailfor a target address.- Fire guesses at
GET /api/auth/callback/email?email=<target>&token=<6-digit>. - 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
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di CapSoftware/Cap
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
CapSoftware/Cap#2305 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
CapSoftware/Cap#1714 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 64/100
CapSoftware/Cap#2360 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 78/100
CapSoftware/Cap#2359 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
CapSoftware/Cap#2357 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di CapSoftware/Cap
Issue simili
-
area:casework bug criticality:p3 triage:needs-implementation
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
registrystack/registry-stack#1623 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
leptos-rs/leptos#4885 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
longbridge/gpui-kit#3276 ·
I maintainer di solito rispondono entro 1 giorno
-
A-Migration Guides D-Straightforward S-Ready-For-Implementation X-Uncontroversial
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
bevyengine/bevy-website#2607 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno