Prevent session fixation on login

login() kept the existing session id and CSRF token. Anyone who knew
the id before (e.g. via cookie injection) was logged in as the victim
afterwards and knew the CSRF token, too.

- login() clears the session after a successful check. Since the fix of
  Session.clear() this deletes the old store entry, drops the CSRF
  token, resets the timestamps and assigns a new id.
- open_session no longer adopts signed ids without a store entry, so an
  id chosen by the client never becomes a session id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
finnandClaude Opus 5.5 committed 2026-10-21 11:51:35 +00:00
1 parent cc3d064e64
commit fc24ba068d
2 files changed
+7 -1

No files matched your search

+2
View File
@@ -22,6 +22,8 @@ def login(email, password):
if not user.enabled:
return t("This account is not enabled!")
# Start a new session (new id, new CSRF token) against session fixation.
session.clear()
session["user_id"] = user.id
return None
+5 -1
View File
@@ -134,8 +134,12 @@ class SessionInterface(FlaskSessionInterface):
session_id = session_id.decode("utf-8", "strict")
data = session_storage[session_id]
if data is None:
# Never adopt an id chosen by the client (session fixation)
return self.make_session_object()
session = self.make_session_object(session_id, data=data)
if data is not None and session.is_expired(time.monotonic()):
if session.is_expired(time.monotonic()):
del session_storage[session_id]
return self.make_session_object()
return session