fix: re-validate GitHub OAuth token every 24h to detect revocation (GHSA-6c5j-4w43-2v8f #2)#594
Closed
advikdivekar wants to merge 9 commits into
Closed
Conversation
- Wrap req.json() in try/catch — returns 400 on malformed JSON - Validate body is a non-null object before destructuring - title: must be non-empty string, trimmed, max 100 characters - target: must be integer in [1, 10000] — blocks 0, negatives, floats, NaN, overflow - unit: clamped to 30 chars silently - recurrence: unknown values default to 'none' explicitly - All bounds defined as named constants Fixes division-by-zero (target:0 → Infinity% progress bar) and negative target making 0-progress goals show as 100% complete. Closes Priyanshu-byte-coder#454
JWT callback now stamps accessTokenValidatedAt on sign-in and makes a lightweight GET /user call every 24 hours. A 401 response sets token.error = "TokenRevoked"; the dashboard redirects to /?error=TokenRevoked so users are prompted to re-authenticate. Network errors and GitHub 5xx responses leave the session intact. Type declarations updated to include error and accessTokenValidatedAt on Session and JWT interfaces.
|
@advikdivekar is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel. A member of the Team first needs to authorize it. |
GSSoC Label Checklist 🏷️@Priyanshu-byte-coder — please apply the appropriate labels before merging: Difficulty (pick one):
Quality (optional):
Validation (required to score):
|
Contributor
Author
|
Closing — patch will be submitted through the private advisory fork (GHSA-6c5j-4w43-2v8f) to avoid public disclosure before coordinated release. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The NextAuth
jwtcallback stored the GitHub OAuth access token at sign-in and never re-validated it. Theaccountobject is only populated on the first sign-in event — every subsequent JWT refresh skipped that block entirely. The 30-day JWT continued to hold and submit a revoked token for its full lifetime with no detection.A user who revoked DevTrack's access via GitHub Settings had no way to actually invalidate the session — DevTrack kept appearing authenticated and kept submitting the revoked token as
Authorization: Beareron every API call for up to 30 days.Root cause: No periodic token validation in the
jwtcallback. Theerrorfield was absent from type declarations, so there was no type-safe path to signal revocation downstream.What changed
src/lib/auth.tstoken.accessTokenValidatedAt = Date.now()alongside the access tokenGET /usercall to the GitHub API401response → setstoken.error = "TokenRevoked"200response → updatestoken.accessTokenValidatedAt, clears any prior errorsessioncallback now surfacestoken.errorintosession.errorsrc/types/next-auth.d.tserror?: stringto theSessioninterfaceaccessTokenValidatedAt?: numberanderror?: stringto theJWTinterfacesrc/app/dashboard/page.tsx/?error=TokenRevokedwhensession.error === "TokenRevoked"How to verify
/dashboardwithout signing out — within 24 hours the page redirects to/?error=TokenRevokedsession.errorcompiles without type error across the codebaseRegression check
session.accessToken: unchangedSESSION_MAX_AGEandSESSION_UPDATE_AGE: unchangedFixes GHSA-6c5j-4w43-2v8f vulnerability #2 (High).