Skip to content

fix: update transaction cookie deletion to clear all cookies on succe…#2464

Closed
rajyan wants to merge 1 commit into
auth0:mainfrom
rajyan:fix/issue-1917-infinite-stacking-cookies
Closed

fix: update transaction cookie deletion to clear all cookies on succe…#2464
rajyan wants to merge 1 commit into
auth0:mainfrom
rajyan:fix/issue-1917-infinite-stacking-cookies

Conversation

@rajyan

@rajyan rajyan commented Dec 14, 2025

Copy link
Copy Markdown
  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

📋 Changes

This PR fixes the transaction cookie accumulation issue by calling deleteAll in handleCallback upon successful authentication.

Problem:
In v4, transaction cookies (__txn_*) accumulate over time as users navigate the app while unauthenticated. This eventually causes 431 errors due to request header size limits.

Solution:

  • Changed handleCallback to call transactionStore.deleteAll() instead of transactionStore.delete(state) after successful authentication
  • This ensures all accumulated transaction cookies are cleaned up when a user successfully logs in
  • Complements the existing deleteAll call in handleLogout

Changed files:

  • src/server/auth-client.ts: Replace delete(state) with deleteAll() in handleCallback
  • src/server/redundant-txn-cookie-deletion.test.ts: Update test to verify all transaction cookies are deleted on success

📎 References

🎯 Testing

Unit tests:

  • Updated redundant-txn-cookie-deletion.test.ts to verify that all transaction cookies are deleted after successful callback
  • All existing tests pass

Manual testing (verified locally):

  1. Started the app and navigated around while unauthenticated (created multiple __txn_* cookies)
  2. Logged in successfully
  3. Verified all __txn_* cookies were cleared from the browser

@rajyan
rajyan requested a review from a team as a code owner December 14, 2025 07:06
@rajyan rajyan mentioned this pull request Dec 14, 2025
6 tasks
@Piyush-85

Copy link
Copy Markdown
Contributor

Hey @rajyan — thank you for putting this together and for the thorough writeup. The root cause diagnosis is exactly right and this approach works for the common case. We're closing this in favour of a more targeted fix we're landing internally, wanted to explain why rather than just closing.

Why deleteAll() on callback breaks a valid use case

deleteAll() is correct when there's only one in-flight login at a time, but it breaks multi-tab prompt: login flows:

  1. Tab A starts login → __txn_stateA written
  2. Tab B starts login under a different account (prompt: login) → __txn_stateB written
  3. Tab A completes callback → deleteAll() fires → __txn_stateB is wiped
  4. Tab B returns from Auth0 → no matching cookie → InvalidStateError

This is a real pattern for apps with account-switching flows, and it's the reason enableParallelTransactions: true exists as the default.

What we've proposed instead

The fix we're landing addresses accumulation at both ends without this side-effect:

Fix 1 — Prefetch guard
Return 401 on non-navigational requests to /auth/login using sec-fetch-mode: navigate as the primary signal (W3C Fetch Metadata, broadly supported),
with fallbacks for older environments. Stops prefetch cookies from being written in the first place. Controlled by dangerouslyAllowLoginPrefetch (default
false).

Fix 2 — Value-prefix encoding + two-phase eviction
Cookie values are now encoded as p:{jwe} for prefetch requests and {epoch_ts}:{jwe} for real logins. Classification is O(1) — no decryption needed.
When accumulated size hits maxSizeBytes (default 4 KB), two-phase eviction runs: phase 1 deletes all p: cookies (always garbage, always safe); phase 2
evicts oldest real logins by timestamp prefix. Backward compatible with legacy bare {jwe} format.

Fix 4 — Targeted cleanup on callback
Instead of deleteAll(), on successful callback we call deletePrefetchCookies() (sweeps all p: cookies) followed by delete(state) (removes only the
completing flow's cookie). All other real in-flight cookies from other tabs are completely untouched.

Thanks again for the contribution — the diagnosis and test structure here were genuinely useful signal.

@Piyush-85 Piyush-85 closed this Jul 6, 2026
@rajyan

rajyan commented Jul 6, 2026

Copy link
Copy Markdown
Author

Thanks for the detailed explanation. The targeted approach makes sense and looks like the right fix!

@kenkoooo

Copy link
Copy Markdown
Contributor

This: #2748

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.

v4: Infinitely stacking cookies

3 participants