top of page

Case study JWT access token with excessively long expiration



Scope: We was given Swagger documentation of company new service APIs for release




We found that the application’s JWT access tokens (used for API authentication in most of the APIs) had an unusually long validity period (e.g., 7–30 days) and were not tied to any server‑side revocation or rotation mechanism. Once issued, a stolen token remained valid until its natural expiration, regardless of logout, password change, or role changes.

This meant an attacker who obtained a single valid JWT (through XSS, local storage theft, browser cache, or proxy compromise) could maintain persistent access to user APIs, even after the user believed they had logged out or changed credentials.


Why this matters now

  • Modern SPAs and mobile apps almost universally use JWT/OAuth‑style tokens for API auth.

  • Long‑lived tokens + no revocation = “bearer keys” that act like long‑term passwords if compromised.

  • Employees change roles, access should be revoked quickly; static, long‑lived tokens preserve outdated permissions long past the business decision.

For a security‑sensitive service (fintech, SaaS admin console, Web3 dashboards), this is unacceptable risk.

1. Short‑lived access tokens

  • Set JWT access token lifetimes to something like 15–30 minutes for user‑facing apps.

  • Include: exp, iat, and a unique jti (token ID) claim.

  • Validate expiry on the server; never trust client‑side time checks.

2. Use refresh tokens + rotation

  • Issue a separate refresh token (HTTP‑only, secure cookie or secure storage) with a longer but bounded lifetime (e.g., 7–30 days).

  • Refresh flow:

    • Client sends refresh token to a dedicated /auth/refresh endpoint.

    • Server verifies refresh token, issues new short‑lived access token and a new refresh token, and invalidates the old refresh token (rotation).

    • Store refresh tokens server‑side (DB/Redis) with status and last‑used metadata; reject reused or revoked tokens.

3. Implement token revocation and logout

  • Maintain a revocation list or state table for tokens (access and/or refresh) keyed by jti or session ID.

  • On logout, password reset, or high‑risk events (suspicious login, role change), revoke all active tokens for that user/session.

  • APIs should check token status (and expiry) on each request and reject revoked tokens even if exp is still in the future.

4. Scope tokens and minimize claims

  • Include only necessary claims (user ID, roles, tenant) and avoid embedding sensitive data or excessive privileges.

  • Use different token scopes for user vs admin operations, with stricter expiry and monitoring on privileged scopes.





Previously foud access

Comments


bottom of page