Skip to content

fix(security): stop exposing GitHub access token on client-visible session (#2845)#3132

Open
BCA-krishna wants to merge 1 commit into
Priyanshu-byte-coder:mainfrom
BCA-krishna:fix/issue-2845-core-auth
Open

fix(security): stop exposing GitHub access token on client-visible session (#2845)#3132
BCA-krishna wants to merge 1 commit into
Priyanshu-byte-coder:mainfrom
BCA-krishna:fix/issue-2845-core-auth

Conversation

@BCA-krishna

Copy link
Copy Markdown
Contributor

Closes #2845

What changed and why

The NextAuth session() callback in src/lib/auth.ts was copying the
raw GitHub OAuth access token onto the session object. Since session
is returned to the browser via useSession()/getSession(), any
JavaScript on the page — including an XSS payload — could read the token
and gain full GitHub API access with the granted scopes.

Files changed (3 files only)

  • src/lib/auth.ts — removed session.accessToken = token.accessToken
    from the session() callback. Token stays in the encrypted HttpOnly
    JWT cookie only.
  • src/lib/get-session-token.ts — added getAccessToken(), a
    server-only helper that reads the token directly from the JWT via
    next-auth/jwt's getToken(), for use in API route handlers.
  • test/auth.test.ts — updated test to assert that accessToken is
    NOT present on the session object (previously asserted the opposite).

Follow-up

API routes that currently read session.accessToken will be migrated to
getAccessToken() in a follow-up PR. Those routes are all server-side
(src/app/api/) and never reach the browser, so they continue to work
correctly via the session callback until migrated.

Testing

  • npm run type-check — 0 errors
  • npm run lint — 0 errors
  • npm test — auth.ts tests all pass (18/18)

…ssion

The NextAuth session() callback was copying the GitHub OAuth access token
onto the session object, which is returned to the browser via
useSession()/getSession(). Any JavaScript running on the page —
including a successful XSS payload — could read it directly.

Changes:
- Remove session.accessToken assignment from the session() callback in
  src/lib/auth.ts; the token now stays only in the encrypted HttpOnly
  JWT cookie that NextAuth manages and never reaches the browser.
- Add getAccessToken() to src/lib/get-session-token.ts: a server-only
  helper that reads the token directly from the JWT via next-auth/jwt
  getToken(), for use in API route handlers.
- Update test/auth.test.ts to assert that accessToken is NOT present on
  the session object (was asserting the opposite before this fix).

API routes that still read session.accessToken will be migrated to
getAccessToken() in a follow-up PR to keep this change reviewable.

Closes Priyanshu-byte-coder#2845
@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 Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

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 Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc26 GSSoC 2026 contribution 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

1 participant