You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Step-up re-authentication does not rotate the session id (CSRF token does rotate) #369
When step-up (SUF-02) re-runs the passkey login ceremony while the user is already authenticated, the servlet session id (JSESSIONID) is not rotated. The CSRF token is rotated. This was verified in a browser as part of SpringUserFrameworkDemoApp#75, whose acceptance criteria expected the session id to change on re-assertion.
Captured immediately before submitting a gated operation and immediately after the step-up ceremony (/login/webauthn re-run mid-session):
JSESSIONID before = 562CB176BDC07A3C3910BEAE8BE5BE9C
JSESSIONID after = 562CB176BDC07A3C3910BEAE8BE5BE9C (unchanged)
_csrf before = 5918qjK-pVpDMMp00naRBGQJb-5In7sVocHP3LlHgGRPzEV...
_csrf after = hYOlzFKos_wbhhMEBPW3qm8UwP5PLxcDAPiIgaixc3cY8_9... (rotated)
Why this happens
Step-up depends on factor merging (setMfaEnabled(true) on the authentication processing filters, MfaFilterMergingConfiguration). In MFA/merge mode the filter merges the new factor onto the already-authenticated principal rather than running a fresh authentication, so the session-fixation strategy (ChangeSessionIdAuthenticationStrategy) does not rotate the id. CsrfAuthenticationStrategy still runs, so the CSRF token rotates.
Is it a problem?
Arguably not a vulnerability: the principal is unchanged and the session was already authenticated, so preserving the id introduces no fixation vector (there is no pre-auth id being "upgraded"). But it contradicts the reasonable expectation — stated in the demo issue's acceptance criteria — that a full re-login rotates the session id, and it is worth documenting the intended behavior either way.
Ask
Confirm whether preserving the session id across a step-up re-assertion is intended, and document it (CONFIG.md / MIGRATION.md) alongside the note that CSRF rotates.
If id rotation is desired for step-up, decide how that interacts with factor merging (which deliberately does not rotate on each factor).
Client consequence already handled in the demo: because CSRF rotates, a client that stays on the page after step-up must refresh its CSRF token before retrying (SpringUserFrameworkDemoApp#75 adds a GET /csrf for exactly this).
Documented in CONFIG.md (step-up section) via #372 / 7d504ad.
Confirmed the behavior is intended: step-up re-assertion preserves the servlet session id (JSESSIONID) while rotating the CSRF token, because factor merging merges the new factor onto the already-authenticated principal rather than running a fresh authentication. No session-fixation vector exists (principal unchanged, no pre-auth id being upgraded), so the id is deliberately not rotated. The added note also documents the client consequence: a client retrying a gated operation after step-up must refresh its CSRF token first.
Activity
fix: retry concurrent passwordless registration deadlocks (#368); doc…
devondragon commentedon Aug 21, 2026
Documented in CONFIG.md (step-up section) via #372 / 7d504ad.
Confirmed the behavior is intended: step-up re-assertion preserves the servlet session id (
JSESSIONID) while rotating the CSRF token, because factor merging merges the new factor onto the already-authenticated principal rather than running a fresh authentication. No session-fixation vector exists (principal unchanged, no pre-auth id being upgraded), so the id is deliberately not rotated. The added note also documents the client consequence: a client retrying a gated operation after step-up must refresh its CSRF token first.