ProblemThe double-submit CSRF cookie in lib/utils/csrf.ts is a single global 64-hex token with a 24 h Max-Age. It is generated once per browser cookie store and only rotated on explicit login/refresh calls (which are themselves backend-disabled TODOs). Any code path that lets a stale token survive a session change (e.g., switching accounts in the same browser profile) keeps an old token alive.
ensureCsrfCookie re-uses any existing valid-length token, so a token minted for one visitor profile is valid for a subsequent one on the same machine.
- Token rotation is only wired to
POST /api/auth/session and POST /api/auth/refresh; refresh/route.ts itself is a stub that only re-issues the CSRF cookie without refreshing the session token.
- There is no per-session or per-user binding (cookie simply holds a random value), so CSRF protection is weaker than a session-bound token.
Solution
- Rotate the CSRF token whenever the authenticated identity changes (login, logout, refresh).
- Store a server-side binding (or session id) so the token is tied to the current user, not just "any browser with the cookie".
- Provide a real refresh implementation before relying on it for rotation.
Acceptance Criteria
- CSRF token changes after login and after logout.
- A token captured from a pre-login page cannot be replayed after a different user logs in.
POST /api/auth/refresh actually refreshes the session, not just re-sets the CSRF cookie.
npm run build passes.
Note for Contributors: Write a clear PR description. Include a capture of the csrf_token cookie before/after login and a replay attempt showing rejection.
ProblemThe double-submit CSRF cookie in
lib/utils/csrf.tsis a single global 64-hex token with a 24 hMax-Age. It is generated once per browser cookie store and only rotated on explicit login/refresh calls (which are themselves backend-disabled TODOs). Any code path that lets a stale token survive a session change (e.g., switching accounts in the same browser profile) keeps an old token alive.ensureCsrfCookiere-uses any existing valid-length token, so a token minted for one visitor profile is valid for a subsequent one on the same machine.POST /api/auth/sessionandPOST /api/auth/refresh;refresh/route.tsitself is a stub that only re-issues the CSRF cookie without refreshing the session token.Solution
Acceptance Criteria
POST /api/auth/refreshactually refreshes the session, not just re-sets the CSRF cookie.npm run buildpasses.Note for Contributors: Write a clear PR description. Include a capture of the
csrf_tokencookie before/after login and a replay attempt showing rejection.