Skip to content

fix(security): remove GitHub access token from client-exposed session#2875

Open
BCA-krishna wants to merge 3 commits into
Priyanshu-byte-coder:mainfrom
BCA-krishna:fix/issue-2845-secure-token-storage
Open

fix(security): remove GitHub access token from client-exposed session#2875
BCA-krishna wants to merge 3 commits into
Priyanshu-byte-coder:mainfrom
BCA-krishna:fix/issue-2845-secure-token-storage

Conversation

@BCA-krishna

Copy link
Copy Markdown
Contributor

Closes #2845

Problem

The NextAuth session() callback copied the GitHub access token onto
the session object. Since session is exposed to client-side code via
useSession()/getSession(), the raw GitHub token was readable by any
JavaScript running on the page — including a successful XSS payload —
giving full access to the user's GitHub account with the granted scopes.

Fix

  • Removed session.accessToken = token.accessToken from the session()
    callback in src/lib/auth.ts. The token now stays only in the
    encrypted, HttpOnly JWT cookie that NextAuth manages — it never reaches
    the browser.
  • Added a getAccessToken() helper in src/lib/get-session-token.ts
    that reads the token server-side only, directly from the JWT via
    next-auth/jwt's getToken().
  • Migrated all API routes that previously read session.accessToken to
    call getAccessToken() instead (29 route files).
  • Updated/added tests to mock getAccessToken() and to assert that
    accessToken is never present on the session object returned to the
    client.

Testing

  • npm run type-check — 0 errors
  • npm run lint — 0 errors (5 pre-existing unrelated <img> warnings)
  • npm test — same failure count as main (all pre-existing/unrelated
    to this change — verified via git stash comparison); no new failures
    introduced by this fix

@github-actions github-actions Bot added gssoc26 GSSoC 2026 contribution type:bug GSSoC type bonus: bug fix type:security GSSoC type bonus: security (+20 pts) type:testing GSSoC type bonus: tests (+10 pts) labels Jun 27, 2026
@github-actions

Copy link
Copy Markdown

GSSoC Label Checklist 🏷️

@Priyanshu-byte-coder — please apply the appropriate labels before merging:

Difficulty (pick one):

  • level:beginner — 20 pts
  • level:intermediate — 35 pts
  • level:advanced — 55 pts
  • level:critical — 80 pts

Quality (optional):

  • quality:clean — ×1.2 multiplier
  • quality:exceptional — ×1.5 multiplier

Validation (required to score):

  • gssoc:approved — counts for points
  • gssoc:invalid / gssoc:spam / gssoc:ai-slop — does not score

Type labels (type:*) are auto-detected from files and title. Review and adjust if needed.
Points formula: (difficulty × quality_multiplier) + type_bonus

@github-actions github-actions Bot added type:feature GSSoC type bonus: new feature type:performance GSSoC type bonus: performance (+15 pts) labels Jun 27, 2026

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Good security fix — consistently replaces session.accessToken with server-side getAccessToken() across all routes. Large but systematic change.

@Priyanshu-byte-coder Priyanshu-byte-coder added gssoc:approved GSSoC: PR approved for scoring level3 GSSoC Level 3 - Advanced (45 points) labels Jul 1, 2026
@Priyanshu-byte-coder

Copy link
Copy Markdown
Owner

Approved — has merge conflicts now (58 files changed, likely conflicts from recent activity). Please rebase on main.

@BCA-krishna

Copy link
Copy Markdown
Contributor Author

Approved — has merge conflicts now (58 files changed, likely conflicts from recent activity). Please rebase on main.

Done! I've rebased on the latest main, resolved the conflicts, and pushed the updated branch. Thanks for the review!

@Priyanshu-byte-coder

Copy link
Copy Markdown
Owner

Removing the GitHub access token from the client-exposed session is a change we want — but 59 files with a failing check is too much surface to review safely in one PR. Please fix CI and, if possible, split into the session/auth core change plus follow-ups.

- Stop copying accessToken onto the NextAuth session object in the
  session() callback (auth.ts), since session is exposed to client-side
  JS via useSession()/getSession() and was readable via XSS (Priyanshu-byte-coder#2845)
- Add getAccessToken() helper (lib/get-session-token.ts) that reads the
  token server-side only, directly from the encrypted JWT cookie via
  next-auth/jwt's getToken()
- Migrate all API routes that previously read session.accessToken to
  use the new server-only getAccessToken() helper instead
- Update/add tests to mock getAccessToken() and verify accessToken is
  no longer present on the session object

Closes Priyanshu-byte-coder#2844
@BCA-krishna BCA-krishna force-pushed the fix/issue-2845-secure-token-storage branch from b4143a8 to 2fa216f Compare July 4, 2026 09:48
@BCA-krishna

Copy link
Copy Markdown
Contributor Author

Core auth fix submitted as a smaller, focused PR #3132 (3 files only).
This PR (#2875) contains the follow-up API route migrations.
Please review #3132 first, then this one.

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

Labels

gssoc:approved GSSoC: PR approved for scoring gssoc26 GSSoC 2026 contribution level3 GSSoC Level 3 - Advanced (45 points) type:bug GSSoC type bonus: bug fix type:feature GSSoC type bonus: new feature type:performance GSSoC type bonus: performance (+15 pts) type:security GSSoC type bonus: security (+20 pts) type:testing GSSoC type bonus: tests (+10 pts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SECURITY] GitHub personal access tokens stored in plaintext browser localStorage are accessible to any JavaScript running on the page

2 participants