Skip to content

CSRF token is reused across login/users with no per-session binding #486

Description

@therealjhay

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.

  1. 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.
  2. 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.
  3. 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.

Activity

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

Metadata

Metadata

Labels

Stellar WaveIssues in the Stellar wave program

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions