Sessions that survive logout and password changes
What it looks like
// app/api/logout/route.ts
export async function POST() {
cookies().delete('session'); // browser copy removed
return redirect('/login'); // server copy still valid
}
// change-password handler: updates the hash, touches no sessionsWhat happens
Someone who once had a user's token, on a shared computer or through a leak, keeps access after the user logs out or changes their password.
Where it shows up
Descriptive, not a verdict: builders and stacks whose defaults make this reachable, or that a public incident names. Each hub states the tool's own security features.
Check it yourself
Uses your builder's dashboard and your browser. No tools to install.
- Sign in, open developer tools (right-click, Inspect), go to the Network tab and use Copy as cURL on a request that returns your account data.
- Sign out in the app, then run the copied command in a terminal.
- Sign in again, change your password, then run the command you copied before the change.
- Sign in on a second browser, change your password on the first, and reload the second.
A bad result is your account data still coming back, or the second browser staying signed in.
What we check
We capture tokens and cookies, then replay them after logout, password change and a global sign-out, and measure how long a captured token keeps working. The report gives the window for each.
Fix direction
Destroy the session on the server at logout and on password change, and regenerate the session id after any privilege change, as the OWASP session cheat sheet describes. With Supabase, signOut with the global scope removes the sessions from the database and a short JWT expiry limits how long an issued token lives; Firebase offers revokeRefreshTokens with the checkRevoked flag.
Mechanism documented in: Session Management Cheat Sheet (verified 2026-09-21); User sessions (verified 2026-09-21).
Covered by
Pre-launch check ($490, 48 hours) and Security sweep ($290, 24 hours)
Both include a re-check after your fixes.
Related patterns
- Tokens trusted without server verificationLogin and permissionsCritical
Anyone can write their own token naming another user, or an admin, and the server will act as that person.
- Password reset links that never expireLogin and permissionsHigh
An old reset email found in a shared inbox, a forwarded thread or a breached mailbox lets someone take over the account months later.
- Authorization enforced only in the browserLogin and permissionsCritical
Anyone who calls the API directly, or edits the page in developer tools, gets the data and actions the screen was hiding.
- Subscription state trusted from local storagePaymentsHigh
Anyone can type one line in the browser console to become a paying customer, and the server hands over the paid feature without checking.
Questions
does logging out actually invalidate my session
Only if the server destroys its copy. Deleting the cookie in the browser removes your copy, but a token captured earlier keeps working until the server forgets it or it expires. OWASP's session guidance is to destroy the session server-side on logout. The Copy as cURL test in the self-check shows which case your app is in.
should changing password log out other devices
Yes, or at least give the user that option. OWASP recommends renewing the session id after any privilege change, including a password change. Supabase's docs describe signOut with the global scope, which removes the user's sessions from the database; Firebase's Admin SDK offers revokeRefreshTokens. Test it by changing your password in one browser and reloading another.
how long does a supabase session last
Supabase's docs say sessions last indefinitely by default until the user signs out, changes their password or a configured limit ends them; time-box and inactivity timeouts are available on paid plans. The access token itself is a short-lived JWT that is refreshed, and Supabase notes it cannot revoke an access token before it expires, so a shorter JWT expiry narrows the window. Check the sign-out behaviour with the self-check above.
Back to the catalogue, or run the self-check for your stack.