pallets-eco / flask-session

Server side session extension for Flask
https://flask-session.readthedocs.io
BSD 3-Clause "New" or "Revised" License
488 stars 236 forks source link

Revoking sessions #222

Open Lxstr opened 3 months ago

Lxstr commented 3 months ago

https://github.com/christopherpickering/flask-session2/issues/21

As noted in this fork, revoking sessions using an alternative id method. It is possible we have an alternative id that is used to link the the actual user data. If we change the alternative id in the user data (probably stored on database) then the session no longer links to that data and becomes invalid. This method seems ok but there would be some implementation logic. It would also seem strange storing session information, we could store things in the session but we would have to check the alternative id matches a user in the database every time we use any session data. It's possible then that you could be storing all the session info in the database and only keep the alternative id in the session storage (eg redis).

The other option is storing a list of session ids the the database which can be used to delete those sessions from storage if the user desires. It could even be a list of abbreviated session-ids and the relevant user agent if it needs to be presented to the user.

I suspect that flask-session need not really be involved in either of these options, but open to input

Lxstr commented 3 months ago

Second option example


@app.route("/login/", methods=["POST", "GET"])
def login():

    form = LoginForm()
    if form.validate_on_submit():
        email = form.email.data
        password = form.password.data
        try:
            auth.login(email, password)
        except Exception as e:
            return redirect("/login")

        # Mitigate session fixation attacks
        # If the session is not empty (/add-apple/ was previously visited), the session will be regenerated
        old_session_id = session.sid
        app.session_interface.regenerate(session)
        new_session_id = session.sid

        # Assuming there's a function update_session_ids(old_id, new_id) defined elsewhere that handles the database update
        # This updates a list of session ids associated with a user in the main database (not session storage)
        update_session_ids(old_session_id, new_session_id, session["user_id"])

        session["logged_in"] = True
        return "logged in"