AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Auth: Invite And Recovery Links Create A Persistent Authenticated Session Before Password Is Set

Supabase Auth's exchangeCodeForSession for invite and recovery links persists a full session. The JWT has no pending_password or amr claim, so applications cannot reliably gate sensitive routes, allowing invited/recovering users to reach authenticated pages before setting a password.

highConfidence 82%Next.js

Origin Analysis

GoTrue treats recovery and invite codes like magic links: it issues a standard session at code exchange without adding a pending_password_set claim or AMR marker to the JWT, and the session remains valid after navigation, so it is indistinguishable from a normal login.
1. Admin invites a user via inviteUserByEmail. 2. User clicks the link in Browser A; callback exchangeCodeForSession creates a session and redirects to /set-password. 3. User opens the same link in Browser B, creating another session. 4. User returns to Browser A and opens /; the app treats them as fully authenticated without having set a password.

Fixing Code Block

Edge Case Audit

This is an app-level workaround, not server-side GoTrue enforcement. It relies on cookie and middleware covering all routes; API routes and direct Supabase calls bypass it. Additionally, if an attacker deletes the cookie, the full session remains valid because the JWT is unchanged, so RLS policies on sensitive tables must independently deny pending-password users. Rollback: remove cookie logic and middleware; be aware that users with pending password may have full access. The fix should be replaced by first-class GoTrue support (pending_password claim or scoped session) once available.

Ecosystem Topology