27

How do I create a new clean session and invalidate the current one in Flask?

Do I use make_null_session() or open_session()?

4 Answers 4

31

I do this by calling session.clear().

EDIT:

After reading your comment in another answer, I see that you're trying to prevent a replay attack that might be made using a cookie that was issued in the past. I solved that problem as much as possible* with this approach:

  • Override SecureCookieSessionInterface.save_session(), copying the code from the overridden version rather than calling it.
  • When the overridden version of save_session() calls save_cookie(), make it pass a session_expires argument 30 minutes in the future. This causes cookies more than 30 minutes old to be considered invalid.
  • Make the overridden version of save_session() update a session variable every so often, to make sure the cookie and its session_expires time get rewritten regularly. (I name this session variable '_refresh' and store the current time in it, then rewrite it only if more than a few seconds have passed since the last-stored time. This optimization avoids rewriting the cookie on every HTTP request.)

Duplicating Flask code in the custom save_session() makes this approach a bit ugly and brittle, but it is necessary in order to change the arguments passed to save_cookie(). It would be nice if Flask made this easier, or at least implemented its own safeguard against replay attacks.

*WARNING: This approach by itself will not stop replay attacks that might happen during a session cookie's valid lifetime. This fundamental problem with cookie-based sessions is discussed in RFC 6896 and A Secure Cookie Protocol by Liu, Kovacs, Huang, Gouda.

Sign up to request clarification or add additional context in comments.

4 Comments

This doesn't seem to invalidate the current session. Do you know if that is possible to do?
Flask's built-in sessions are cookie-based with hashes and timestamps for validation, so there's no such thing as invalidating them in the way that you would with a key-based database-storage-backed session. You could override SecureCookieSessionInterface.save_session() to call save_cookie() with a session_expires argument in the past, but why bother? Calling session.clear() removes all data from the session, leaving it empty. Isn't that good enough?
Oh, I see what you're after. I just edited my answer with an approach that should help you.
If session_expires set to 30 minutes, users will be logged out from their sessions after 30 minutes of inactivity.
12

If you have security concerns (and everyone should have) There is the answer:

This is not REALLY possible

Flask uses cookie-based sessions. When you edit or delete session, you send a REQUEST to CLIENT to remove the cookie, normal clients (browsers) will do. But if session hijacked by an attacker, the attacker's session remains valid.

1 Comment

I am not certain what you mean by saying that normal clients (browsers) would remove the cookie on logout. I don't see that happening in Chrome or FF. Now when I say logout, I would expect the framework, Flask in our case, to invalidate the session in the backend, irrespective of what the client prefers to do with the cookie. I would agree that Flask-Login is apparently handling sessions with cookies or more precisely, the logout_user() from Flask-Login is may be not doing what it sounds to be doing.
11

You can add an after_request callback to remove the session cookie if a particular flag is set:

@app.after_request def remove_if_invalid(response): if "__invalidate__" in session: response.delete_cookie(app.session_cookie_name) return response 

Then you simply set that session key whenever you want to invalidate the session:

@app.route("/logout") def logout(): session["__invalidate__"] = True return redirect(url_for("index")) 

See also: http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.BaseResponse.delete_cookie

3 Comments

But will this invalidate the current session? I want to make it so that the user tries to use the old session cookie, it will not work. Is this possible?
@Tyilo - Are you worried about replay attacks?
@Tyilo - You'll want to take a look at stackoverflow.com/a/12472337/135978 for a good starting point there.
2

If you use default flask sessions and set the app.permanent_session_lifetime, then the session will not work if a user tries to replay the same session as long as the session has expired.If you look at the source code for open_session, there is line:

max_age = total_seconds(app.permanent_session_lifetime) try: data = s.loads(val, max_age=max_age) return self.session_class(data) except BadSignature: return self.session_class() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.