# Token purpose and lifecycle not enforced

Signed tokens reused across endpoints or after logout because purpose, exp, or revocation is never checked

_Area: Web authentication and account takeover. Seen in 3 disclosed reports; one confirmed bounty: $10,000; latest 2026-07-28. Updated 2026-10-24._

## How it works
A signed token proves *who* issued it, not *what it is for* or *whether it is still valid*. Systems assume that a valid signature plus the right subject claims is enough to authorize an action. When tokens for different purposes share the same claim set, or when revocation depends on a claim that may be absent, the signature check passes while the intended restriction silently does not exist.

## Where it shows up
- Lifecycle endpoints (`/installed`, `/uninstalled`, `/enabled`) that verify a JWT signature but not binding claims such as `qsh` [E1](https://bugbountylibrary.com/r/bc%3Aad5e53a0-d477-4dc9-8bda-4ec8d702364f.md)
- One token-minting routine reused for many purposes (upload, download, websocket, backup) with identical claims [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-8r6w-3qq5-4p4r.md)
- Daemons or services that validate only signature + `server_uuid`/`user_uuid`/`unique_id` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-8r6w-3qq5-4p4r.md)
- "Never expire" or `expiry=0` options that omit the `exp` claim [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md)
- Revocation code that early-returns on `remainTTL<=0`, or dereferences a nil `ExpiresAt` [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md)
- Admin delete paths that remove the DB row without blacklisting the JTI [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md)

## How to review
For each token, identify the exact endpoint(s) it is meant for and the property that must hold: the token must encode its purpose (audience/scope/`qsh`), carry a bounded `exp`, and be checked against a revocation store on every privileged action. Trace every mint site and confirm the claim set differs by purpose or that the receiving endpoint enforces scope. For each revocation path (logout, admin delete, revoke API), confirm it works for *every* token class, including no-exp tokens. A token captured from a low-privilege context must fail against a higher-privilege endpoint.

## Variants seen
- Missing `qsh` validation on a Connect lifecycle endpoint, allowing baseurl rewrite and OAuth token interception [E1](https://bugbountylibrary.com/r/bc%3Aad5e53a0-d477-4dc9-8bda-4ec8d702364f.md)
- Identical claims across purposes, enabling cross-endpoint reuse from websocket token to file upload [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-8r6w-3qq5-4p4r.md)
- No-exp tokens where all three revocation paths fail (panic, TTL early-return, no JTI blacklist) [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md)

## Why fixes fail
Revocation logic keyed on `exp` breaks precisely for tokens without one; fixing logout alone leaves admin delete and blacklist writers still skipping the token [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md).

## Impact and severity
OAuth token and user-data theft [E1](https://bugbountylibrary.com/r/bc%3Aad5e53a0-d477-4dc9-8bda-4ec8d702364f.md), privilege escalation from subuser to arbitrary file upload [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-8r6w-3qq5-4p4r.md), and permanently valid leaked credentials [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md). Severity rises when tokens are long-lived or never-expiring and when no revocation path exists.

## Evidence
- E1: https://bugbountylibrary.com/r/bc%3Aad5e53a0-d477-4dc9-8bda-4ec8d702364f.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-8r6w-3qq5-4p4r.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-fpw6-hrg5-q5x5.md
