CVE-2026-86698: Refresh tokens accepted as private repository credentials at the CDN
Insufficient Session Expiration vulnerability in OAuth token issuance in hexpm hexpm allows a user whose organization membership or session has ended to keep reading the organization's private packages and their documentation tarballs via a retained refresh token.
generaterefreshtoken/4 in lib/hexpm/oauth/jwt.ex signs the refresh token with the same iss, aud and scope claims as the access token, so it carries the same repository:<org> scopes. The CDN service that serves private repositories verifies the signature and time claims and then authorizes from the scope claim, with no database lookup and no way to tell the two token kinds apart. Removing a member or revoking a session therefore takes effect at the CDN only when the 30 day refresh token expires, instead of after the 30 minute access token lifetime. Access is read-only and limited to organizations the account belonged to when the token was granted.
This issue affects hex.pm: from 2025-10-10 before 2026-09-22.
Affected Software
Event History
Frequently Asked Questions
Who can continue accessing private packages after their membership or session ends?
A user who retained a refresh token issued while they belonged to an organization can continue read-only access to that organization's private packages and documentation tarballs. Access is limited to organizations the account belonged to when the token was granted.
What does an attacker need to exploit this issue?
They need a valid retained refresh token with repository:<org> scope for the target organization. The CDN accepts it because it verifies the token signature and time claims, then authorizes based on its scope claims.
Are membership removal and session revocation immediately effective at the CDN?
No. The CDN does not perform a database lookup or distinguish refresh tokens from access tokens, so removal or revocation takes effect there only when the 30-day refresh token expires.
How long can the unintended access persist?
It can persist until the affected refresh token expires, which is 30 days. This is longer than the 30-minute access-token lifetime.
Which deployments are affected?
Affected Hex.pm deployments are those from 2025-10-10 before 2026-09-22.