Skip to content

fix: treat TokenSource JWTs without exp as expired - #1008

Open
SashaMIT wants to merge 1 commit into
livekit:mainfrom
SashaMIT:fix/token-source-require-exp
Open

fix: treat TokenSource JWTs without exp as expired#1008
SashaMIT wants to merge 1 commit into
livekit:mainfrom
SashaMIT:fix/token-source-require-exp

Conversation

@SashaMIT

Copy link
Copy Markdown

Problem

TokenSourceResponse.hasValidToken treated a missing exp as still valid:

val hasExpired = expiresAt != null && now.after(...)
return !isBefore && !hasExpired

TokenSourceCached then keeps serving that response. A JWT with no exp stays cached forever.

nbf is already optional (checked only when present). That part is correct. The hole is the suffix-side missing exp.

This is the Android cache counterpart of livekit/client-sdk-js#2057. Same class as the server-sdk TokenVerifier language-splits (protocol#1706, python-sdks#779, node-sdks#710, server-sdk-ruby#97, server-sdk-kotlin#170). Those require exp on verify. This helper decides whether to refetch.

Fix

Require exp. Keep nbf optional. Leave the existing one-minute after-expiry tolerance unchanged.

Threat-model: the cached participant token is already on the device. The attacker does not need host or TokenSource authority. A token that omits exp never triggers a refetch. The server may still reject the JWT; the client never goes back to the token source.

Test plan

  • ./gradlew :livekit-android-test:testDebugUnitTest --tests io.livekit.android.token.CachingTokenSourceTest (7/7)
  • Revert-tested: restoring expiresAt != null && fails tokenWithoutExpIsInvalid
  • ./gradlew spotlessApply

Made with Cursor

CachingTokenSource.hasValidToken treated a missing exp as still valid, so TokenSourceCached never refetched. Require exp and keep nbf optional, matching client-sdk-js#2057.
@changeset-bot

changeset-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 69d8699

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
client-sdk-android Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant