Skip to content

fix: Session cookie lifetime, renewal, CSRF echo, and current-session… - #117

Merged
m-t-a97 merged 2 commits into
mainfrom
fix/session-cookie-and-sign-out-hardening
Sep 13, 2026
Merged

m-t-a97 merged 2 commits into
mainfrom
fix/session-cookie-and-sign-out-hardening

Conversation

@m-t-a97

@m-t-a97 m-t-a97 commented Sep 13, 2026

Copy link
Copy Markdown
Member

… GET /me and sign-out

Sessions and cookies drifted apart in several places, and both GET /me and POST /sign-out assumed the user's newest session was the current one. A user signed in on two devices could see, or revoke, the wrong session.

Session plugin

  • renew sessions in place instead of delete+create
  • cap cookie Max-Age to the session lifetime; ClearSessionCookie carries SameSite
  • warn at startup when UpdateAge >= ExpiresIn
  • expose the authenticated session id on the request context

CSRF plugin

  • echo X-AUTHULA-CSRF-TOKEN on every safe request
  • compare tokens in constant time

Config

  • CookieMaxAge defaults to and follows ExpiresIn

Core

  • GET /me returns the session that authenticated the request (GetMe now takes sessionID)
  • POST /sign-out with no body revokes the caller's own session; a supplied session_id must belong to the caller (403) and must exist (404); sign_out_all is unchanged; the newest-session fallback remains only for non-cookie actors
  • auth.sign_out (cookie clear) is set only when the caller's own session was revoked, so revoking another session by id keeps the caller signed in
  • CoreAPI.SignOut signature: (ctx, userID, currentSessionID, requestedSessionID, signOutAll)

Admin

  • restored impersonation cookie carries Max-Age

Tests and docs

  • new handler tests for sign-out, rewritten usecase table, extended session/CSRF/config tests
  • docs/core/sign-out.md and updated OpenAPI description

@m-t-a97 m-t-a97 self-assigned this Sep 13, 2026
@m-t-a97
m-t-a97 force-pushed the fix/session-cookie-and-sign-out-hardening branch from 49b95aa to 77db6db Compare September 13, 2026 18:36
… GET /me and sign-out

Sessions and cookies drifted apart in several places, and both GET /me
and POST /sign-out assumed the user's newest session was the current
one. A user signed in on two devices could see, or revoke, the wrong
session.

Session plugin
- renew sessions in place instead of delete+create
- cap cookie Max-Age to the session lifetime; ClearSessionCookie carries
  SameSite
- warn at startup when UpdateAge >= ExpiresIn
- expose the authenticated session id on the request context

CSRF plugin
- echo X-AUTHULA-CSRF-TOKEN on every safe request
- compare tokens in constant time

Config
- CookieMaxAge defaults to and follows ExpiresIn

Core
- GET /me returns the session that authenticated the request
  (GetMe now takes sessionID)
- POST /sign-out with no body revokes the caller's own session (cookie
  or JWT session_id claim); a supplied session_id must belong to the
  caller (403) and must exist (404); sign_out_all is unchanged
- POST /sign-out no longer guesses: with no body and no session id on
  the request it returns 400 (ErrNoSessionToSignOut) instead of
  revoking the user's newest session
- auth.sign_out (cookie clear) is set only when the caller's own session
  was revoked, so revoking another session by id keeps the caller
  signed in
- CoreAPI.SignOut signature: (ctx, userID, currentSessionID,
  requestedSessionID, signOutAll)

Admin
- restored impersonation cookie carries Max-Age

Tests and docs
- new handler tests for sign-out, rewritten usecase table, extended
  session/CSRF/config tests
- docs/core/sign-out.md and updated OpenAPI description
@m-t-a97
m-t-a97 force-pushed the fix/session-cookie-and-sign-out-hardening branch from 77db6db to 5599601 Compare September 13, 2026 19:40
@m-t-a97
m-t-a97 merged commit b567a65 into main Sep 13, 2026
1 of 6 checks passed
@m-t-a97
m-t-a97 deleted the fix/session-cookie-and-sign-out-hardening branch September 13, 2026 19:50
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.

1 participant