-
Notifications
You must be signed in to change notification settings - Fork 0
Fix 2FA bypass vulnerability in NextAuth authorize callback #1
Copy link
Copy link
Open
Labels
P0: criticalCritical — security vulnerability or data lossCritical — security vulnerability or data lossarea: authAuthentication and authorizationAuthentication and authorizationsize: MMedium — 1-2 daysMedium — 1-2 daystype: securitySecurity vulnerability or hardeningSecurity vulnerability or hardening
Milestone
Description
Activity
Metadata
Metadata
Assignees
Labels
P0: criticalCritical — security vulnerability or data lossCritical — security vulnerability or data lossarea: authAuthentication and authorizationAuthentication and authorizationsize: MMedium — 1-2 daysMedium — 1-2 daystype: securitySecurity vulnerability or hardeningSecurity vulnerability or hardening
Projects
- StatusShow more project fieldsTodo
Problem
The TOTP two-factor authentication check is decoupled from the NextAuth
authorizecallback. A determined attacker could skip the/two-factorpage entirely and callsignIn('credentials', ...)directly, bypassing TOTP verification.Current Flow (Vulnerable)
checkTwoFactorStatus(email, password)— validates credentials, returnstwoFactorRequired: boolean/two-factor?email=...verifyTwoFactorLogin()validates itsignIn('credentials', ...)to complete authThe vulnerability: Step 4 calls
signIn('credentials')which goes through theauthorizecallback insrc/lib/auth.ts:32-57. This callback does NOT checktwoFactorEnabled— it just validates email + password and returns the user.Proposed Fix
Option A: Move TOTP into
authorizecallbacktotpCodeparameter in the credentials providerauthorize(), after password validation, check iftwoFactorEnabledis truetotpCodeprovided, throw an errortotpCodeprovided, validate it viaotpauthsignIn()callOption B: Session-level 2FA state
twoFactorVerifiedboolean to the JWTfalseinauthorize()whentwoFactorEnabledis truetwoFactorVerified— if false, redirects to/two-factortwoFactorVerified: trueOption A is simpler and more secure (no intermediate session state). Recommended.
Acceptance Criteria
signIn('credentials', { email, password })call without TOTP fails when 2FA is enabled/two-factorpage still provides the UX for entering the codeFiles to Modify
apps/web/src/lib/auth.ts— authorize callbackapps/web/src/components/login-form.tsx— pass TOTP in signIn callapps/web/src/app/two-factor/page.tsx— update flowapps/web/src/components/settings/two-factor-setup.tsx— verify still works