Authentication Bugs

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

  1. 01Log in as a valid user
  2. 02Navigate to a protected page such as the dashboard and confirm the page loads
  3. 03Open browser DevTools > Network tab and copy the Authorization: Bearer <token> value from that known-authenticated request
  4. 04Log out from the application
  5. 05In a new incognito window, send a request to a protected API endpoint using the copied token
  6. 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
  1. 01Log in as a standard user
  2. 02Open browser DevTools > Network tab
  3. 03Navigate to /dashboard and copy the Authorization: Bearer <token> value from any API request
  4. 04Log out from the application
  5. 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.

// RELATED