Skip to content

Commit

Permalink
Add test for race condition between forced logout and session_save
Browse files Browse the repository at this point in the history
The added test should be able to detect if the code is handling the following scenario: a user is forcibly logged out, maybe due to an admin password change. But if the user is currently logged in, and the forced logout happens between a open_session() ans a save_session() call then the session will be restored and the logout will be ineffective. To prevent this, we need to atomically check if a session already exists in Redis before writing a modified one (the problem should not exists in the case of a new session).
  • Loading branch information
root authored and root committed May 11, 2022
1 parent 19aa75d commit d11545f
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion securedrop/tests/test_journalist_session.py
Expand Up @@ -4,7 +4,7 @@
from datetime import datetime, timedelta, timezone
import re

from flask import url_for
from flask import url_for, Response
from flask.sessions import session_json_serializer
from redis import Redis
from pyotp import TOTP
Expand Down Expand Up @@ -282,3 +282,20 @@ def test_session_bad_signature(journalist_app, test_journo):
headers=get_api_headers(token))
assert resp.status_code == 200
assert resp.json['uuid'] == test_journo['uuid']

def test_session_race_condition(mocker, journalist_app, test_journo):
with journalist_app.test_request_context() as app:
session = journalist_app.session_interface.open_session(journalist_app, app.request)
assert session.sid is not None
session['uid'] = test_journo['id']
app.response = Response()
journalist_app.session_interface.save_session(journalist_app, session, app.response)
assert redis.get(journalist_app.config['SESSION_KEY_PREFIX'] + session.sid) is not None
app.request.cookies = {journalist_app.config['SESSION_COOKIE_NAME']: session.token}
session2 = journalist_app.session_interface.open_session(journalist_app, app.request)
assert session2.sid == session.sid
assert session2['uid'] == test_journo['id']
redis.delete(journalist_app.config['SESSION_KEY_PREFIX'] + session.sid)
journalist_app.session_interface.save_session(journalist_app, session, app.response)
assert redis.get(journalist_app.config['SESSION_KEY_PREFIX'] + session.sid) is None

0 comments on commit d11545f

Please sign in to comment.