CVE-2022-24751: Clear sessions outside of the transaction.

Clearing the sessions inside the transaction makes Zulip vulnerable to
a narrow window where the deleted session has not yet been committed,
but has been removed from the memcached cache.  During this window, a
request with the session-id which has just been deleted can
successfully re-fill the memcached cache, as the in-database delete is
not yet committed, and thus not yet visible.  After the delete
transaction commits, the cache will be left with a cached session,
which allows further site access until it expires (after
SESSION_COOKIE_AGE seconds), is ejected from the cache due to memory
pressure, or the server is upgraded.

Move the session deletion outside of the transaction.

Because the testsuite runs inside of a transaction, it is impossible
to test this is CI; the testsuite uses the non-caching
`django.contrib.sessions.backends.db` backend, regardless.  The test
added in this commit thus does not fail before this commit; it is
merely a base expression that the session should be deleted somehow,
and does not exercise the assert added in the previous commit.
This commit is contained in:
Alex Vandiver
2022-03-09 02:03:42 +00:00
parent c28d1169c3
commit e6eace307e
2 changed files with 20 additions and 1 deletions

View File

@@ -1170,7 +1170,6 @@ def do_deactivate_user(
change_user_is_active(user_profile, False)
delete_user_sessions(user_profile)
clear_scheduled_emails(user_profile.id)
event_time = timezone_now()
@@ -1196,6 +1195,7 @@ def do_deactivate_user(
if settings.BILLING_ENABLED:
update_license_ledger_if_needed(user_profile.realm, event_time)
delete_user_sessions(user_profile)
event = dict(
type="realm_user",
op="remove",