Session Not Expiring After Logout
When a user logs out, their session token or authentication cookie should be invalidated server-side. If the server only clears client-side state but does not revoke the session, the old token continues to work — allowing the user, or anyone who obtained the token, to access protected resources after logout.
CriticalIntermediateSecurity testingAPI testingManual testing
// UNDERSTAND
// Symptoms
- User can access the dashboard or protected pages after logging out
- Browser back button shows a protected page after logout
- An API request sent with the old access token returns 200 OK after logout
- The user remains logged in in a second browser tab after logging out in another
- A refresh token obtained before logout can still generate a new access token
// Root Cause
- Logout only clears client-side cookies or localStorage — the server-side session is not invalidated
- JWT tokens are stateless and valid until expiry; no token revocation mechanism exists — the fix is a server-side blocklist that stores invalidated JTIs (JWT IDs) and rejects any token whose JTI appears in it
- The logout endpoint does not call the token revocation API
- Refresh tokens are not revoked when the access token is invalidated
- Session data is cached and not cleared on logout
// Where It Appears
- Login and logout flows in web applications
- SaaS applications with session-based authentication
- APIs using JWT or OAuth 2.0 access tokens
- Mobile applications with persistent sessions
- Banking and financial applications
- Admin dashboards containing sensitive data
// REPRODUCE & TEST
// How to Reproduce
- 01Log in as a valid user
- 02Navigate to a protected page such as the dashboard and confirm the page loads
- 03Open browser DevTools > Network tab and copy the Authorization: Bearer <token> value from that known-authenticated request
- 04Log out from the application
- 05In a new incognito window, send a request to a protected API endpoint using the copied token
- 06Confirm whether protected data is still returned — it should not be
// Test Data Needed
- A valid user account with access to protected pages
- Browser developer tools to capture session cookies and tokens
- A way to replay HTTP requests (DevTools, Postman, or curl)
- Optionally: a second browser or incognito window to test session isolation
// Manual Testing Ideas
- Log out, then press the browser back button and check whether protected pages load from cache
- Log out in one tab; check whether another tab showing a protected page still allows interaction
- Copy the session cookie before logout; inject it into a new browser session after logout
- Change your password, then attempt to use a session token obtained before the password change
- Disable the account in an admin panel; confirm that existing active sessions are terminated
- Check the Set-Cookie response header on logout for correct expiry or Max-Age=0
// API Testing Ideas
- Call a protected endpoint and capture the 200 response with the bearer token
- Call the logout endpoint
- Replay the same protected request using the original token
- Assert the response is 401 Unauthorized or 403 Forbidden
- Attempt to use the refresh token to obtain a new access token after logout
- Assert that the refresh token endpoint returns 400 or 401, not a new token pair
// Automation Idea
Automate the login flow and capture the bearer token from the Authorization header. Call the logout endpoint. Immediately replay a request to a protected endpoint using the captured token. Assert the HTTP status is 401 or 403. Repeat the check for the refresh token endpoint if the application uses one.
// Expected Result
After logout, all requests using the previously valid session cookie, access token, or refresh token should be rejected with 401 Unauthorized or 403 Forbidden.
// Actual Result (Example)
After logout, a GET request to /api/dashboard/summary with the old bearer token returns 200 OK and exposes the user's dashboard data.
// REPORT IT
Example Bug Report
- Title
- User can access protected dashboard API after logout using old access token
- Severity
- Critical
- Environment
- Staging environment Chrome 124 Standard user account
- Steps to Reproduce
- 01Log in as a standard user
- 02Open browser DevTools > Network tab
- 03Navigate to /dashboard and copy the Authorization: Bearer <token> value from any API request
- 04Log out from the application
- 05Send a GET request to /api/dashboard/summary using the copied bearer token (via curl or Postman)
- Expected Result
- The API returns 401 Unauthorized.
- Actual Result
- The API returns 200 OK and exposes the user's dashboard data.
- Impact
- A logged-out user, or any attacker who obtained the token via network interception or browser history, can continue reading protected user data until the token's natural expiry.