Skip to content

fix(security)!: mitigate session token hashing vulnerability - #246

Merged
halvaradop merged 2 commits into
masterfrom
fix/mitigate-session-token
Aug 2, 2026
Merged

fix(security)!: mitigate session token hashing vulnerability#246
halvaradop merged 2 commits into
masterfrom
fix/mitigate-session-token

Conversation

@halvaradop

@halvaradop halvaradop commented Aug 1, 2026

Copy link
Copy Markdown
Member

Description

This pull request fixes a security vulnerability in the Stateful session strategy related to session token handling.

Previously, the internal session creation flow returned the hashed session token instead of the original randomly generated secret. As a result, the value stored in the database was also used as the authentication credential. If an attacker obtained a copy of the database, they could reuse the stored token hash directly to authenticate requests and hijack active sessions.

This PR changes the session token model to follow a more secure split secret / hash design:

  • A cryptographically secure random session token is generated.
  • The raw session token is returned to the client as a secure, HTTP-only cookie.
  • Only the cryptographic hash of the session token is persisted in the database.
  • During authentication, the incoming session token is hashed and compared against the stored hash.

Because the database never stores the raw session token, a database compromise no longer exposes reusable session credentials.

Key Changes

  • Fixed the session token hashing vulnerability in the Stateful session strategy.
  • Generated a cryptographically secure random session token for each session.
  • Stored only the hash of the session token in the database.
  • Returned the raw session token exclusively to the client as a secure cookie.
  • Updated session validation to hash the incoming token before performing the database lookup.
  • Improved the overall security of database-backed session management.

Security Benefits

  • Prevents reuse of database values as authentication credentials.
  • Mitigates session hijacking following a database compromise.
  • Separates client secrets from persisted database records.
  • Aligns the Stateful session implementation with industry best practices for session token storage.

Previously

Database leak
        ↓
Stored session token
        ↓
Attacker copies the token
        ↓
Authenticated

Now

Database leak
        ↓
SHA-256(sessionToken)
        ↓
Attacker cannot reconstruct the original session token
        ↓
Active sessions remain protected

Note

This change is internal and fully backward-compatible from the API perspective. Applications do not need to modify their authentication flows, as the token hashing and verification process is handled transparently by the Stateful session strategy.

@coderabbitai ignore

@halvaradop halvaradop added the security Security-related changes, vulnerability fixes, or hardening measures. label Aug 1, 2026
@vercel

vercel Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
auth Skipped Skipped Aug 2, 2026 12:00am

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Stateful session handling now stores hashed session tokens, hashes cookie tokens before adapter lookups, and returns plaintext tokens for cookies and authentication responses. Tests were updated to reflect the new token representation.

Changes

Stateful session-token hashing

Layer / File(s) Summary
Separate plaintext and stored session tokens
packages/core/src/session/stateful/createSession.ts, packages/core/src/session/stateful/signInCredentials.ts, packages/core/src/session/stateful/signUp.ts, packages/core/src/session/stateful/oauthCallback.ts
Session creation and OAuth callback flows use plaintext tokens for cookies and responses. Session persistence continues to use token hashes.
Hash tokens before stateful adapter lookups
packages/core/src/session/stateful/*, packages/core/src/shared/utils/api.ts
Stateful session operations hash cookie tokens before calling getSessionByToken.
Update stateful token fixtures and assertions
packages/core/test/actions/**/stateful.test.ts, packages/core/test/api/stateful/*, packages/elysia/test/stateful/index.test.ts
Tests store hashed session values and assert hashed adapter lookups while requests continue to provide plaintext tokens.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: fix

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the security fix for the session token hashing vulnerability.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mitigate-session-token

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/test/actions/providers/connected/stateful.test.ts (1)

76-92: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert that every session lookup uses the hash.

Both tests configure two sequential getSessionByTokenMock results. toHaveBeenCalledWith(tokenHash) only checks that one call matches. A raw-token lookup in the other call can pass this test. Assert both calls with toHaveBeenNthCalledWith and assert the expected call count.

Proposed test assertion
-        expect(getSessionByTokenMock).toHaveBeenCalledWith(tokenHash)
+        expect(getSessionByTokenMock).toHaveBeenCalledTimes(2)
+        expect(getSessionByTokenMock).toHaveBeenNthCalledWith(1, tokenHash)
+        expect(getSessionByTokenMock).toHaveBeenNthCalledWith(2, tokenHash)

Also applies to: 111-128

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/test/actions/providers/connected/stateful.test.ts` around lines
76 - 92, Update the session lookup assertions in both affected tests around
getSessionByTokenMock to verify the exact number of calls and assert each
sequential call with toHaveBeenNthCalledWith using tokenHash, ensuring no lookup
uses the raw token.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/session/stateful/destroySession.ts`:
- Around line 34-35: Update stateful session lookup paths, including
destroySession, refreshSession, getSession, and token-provider lookups, to
recognize legacy cookies containing the stored tokenHash without adding a
permanent raw-cookie fallback. Implement a bounded migration/rotation that
replaces legacy cookies with the current format and preserves revocation,
refresh, and session validation; alternatively, explicitly document and enforce
forced logout consistently.</code>

In `@packages/core/src/shared/utils/api.ts`:
- Around line 59-61: Guard sessionToken in the session lookup flow before
calling createHash, matching the presence check used by getProviderTokens and
revokeToken. When the cookie is missing, follow the existing explicit
missing-session path and return without invoking getSessionByToken; preserve
hashing and adapter lookup for present tokens.

---

Outside diff comments:
In `@packages/core/test/actions/providers/connected/stateful.test.ts`:
- Around line 76-92: Update the session lookup assertions in both affected tests
around getSessionByTokenMock to verify the exact number of calls and assert each
sequential call with toHaveBeenNthCalledWith using tokenHash, ensuring no lookup
uses the raw token.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9238ec8-782b-4c02-b9aa-1e5980f88272

📥 Commits

Reviewing files that changed from the base of the PR and between be5e025 and 1b3a566.

📒 Files selected for processing (25)
  • packages/core/src/session/stateful/createSession.ts
  • packages/core/src/session/stateful/destroySession.ts
  • packages/core/src/session/stateful/getProviderTokens.ts
  • packages/core/src/session/stateful/getSession.ts
  • packages/core/src/session/stateful/isProviderConnected.ts
  • packages/core/src/session/stateful/oauthCallback.ts
  • packages/core/src/session/stateful/refreshSession.ts
  • packages/core/src/session/stateful/revokeToken.ts
  • packages/core/src/session/stateful/signInCredentials.ts
  • packages/core/src/session/stateful/signUp.ts
  • packages/core/src/shared/utils/api.ts
  • packages/core/test/actions/providers/connected/stateful.test.ts
  • packages/core/test/actions/providers/tokens/revoke/stateful.test.ts
  • packages/core/test/actions/providers/tokens/tokens/stateful.test.ts
  • packages/core/test/actions/providers/user/refresh/stateful.test.ts
  • packages/core/test/actions/session/session/stateful.test.ts
  • packages/core/test/api/stateful/getAccessToken.test.ts
  • packages/core/test/api/stateful/getProviderTokens.test.ts
  • packages/core/test/api/stateful/getSession.test.ts
  • packages/core/test/api/stateful/isProviderConnected.test.ts
  • packages/core/test/api/stateful/refreshUserInfo.test.ts
  • packages/core/test/api/stateful/revokeToken.test.ts
  • packages/core/test/api/stateful/signOut.test.ts
  • packages/core/test/api/stateful/updateSession.test.ts
  • packages/elysia/test/stateful/index.test.ts

Comment thread packages/core/src/session/stateful/destroySession.ts
Comment thread packages/core/src/shared/utils/api.ts
@halvaradop
halvaradop merged commit e247ed2 into master Aug 2, 2026
7 checks passed
@halvaradop
halvaradop deleted the fix/mitigate-session-token branch August 2, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security-related changes, vulnerability fixes, or hardening measures.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant