In application I am writing at the moment I've been saving in users browser a cookie that had session ID stored inside, and that ID was used as a reference to a session stored in the database containing user's information including the fact if the user is logged in properly.
I wanted to review the security of my solution and I stared to look into how I should be setting up cookies upon login, what to store in server side stored session and how to destroy that information on logout since as of now my users were staying logged in for ages, which was not my intention.
The problem I have is no definite answer on how to handle the whole user login/session/logout issue properly in Flask - some people are talking about using Flask's Response.delete_cookie() function, others to expire it using .set_cookie() with zero expiration time, others are mentioning Flask's session module, other itsdangerous module...
What is the most secure, right and proper way of handling that in terms of modules that should be used with Flask, code examples and so on?
Flask cookies should be handled securely by setting secure=True, httponly=True, and samesite='Lax' in response. set_cookie(...). If these parameters are not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.
Flask cookies In Flask, set the cookie on the response object. Use the make_response() function to get the response object from the return value of the view function. After that, the cookie is stored using the set_cookie() function of the response object.
You can secure a session cookie by setting an expiration, only allowing encrypted network transmission, blocking third party with the Httponly flag, and configuring where it is stored.
Because it is a stateless protocol, sessions must be managed between the browser side and the server side. With cookie-based session management, a message (cookie) containing user information is sent to the browser by the web server. This cookie is sent back to the server when the user tries to access certain pages.
An easy and safe way to handle sessions is to do the following:
Note that there are a few drawbacks.
Another option is to store all the data in the cookie, and sign (and optionally encrypt) said cookie. This method, however, has numerous shortcomings too:
Flask actually implements signed session cookies already, so it implements method #2.
To get from #2 to #1, all you have to do is:
os.urandom
+ base64
).Make sure you're protected against session fixation attacks. To do so, make sure you generate a new session ID when a user logs in, and do not reuse their existing session ID.
Also, make sure you implement expiration on your sessions (just a matter of adding a "last-seen" timestamp).
You could most likely get some inspiration from Django's implementation.
I would recommend you go with the Flask KVSession plugin with the simplekv module to persist the session information.
Conceptually, Flask KVSession provides an implementation for Method #1 described above using the Flask session interface. That way you don't have to alter your code to get it running, and you can use the extension methods to do additional things such as session expiration. It also takes care of the session signing, and does some basic checks to prevent tampering. You will still want to do this over HTTPS to absolutely prevent session stealing however.
Simplekv is the actual module that handles the writing and reading to various data storage formats. This can be as simple as a flat file, as fast as Redis, or as persistent as a database (NoSQL or otherwise). The reason this is a separate module is so Flask KVSession can just be a plain adapter to Flask without having to know about the storage mechanism.
You can find code samples at http://flask-kvsession.readthedocs.org/en/latest/. If you need more examples, I can provide one.
Alternatively, if you need a more enterprise and heavyweight server sided implementation for Flask, you can also look at this recipe using Beaker which works as WSGI middleware (meaning other frameworks also use it). http://flask.pocoo.org/snippets/61/. The Beaker API is at http://beaker.readthedocs.org/en/latest/.
One advantage Beaker provides over Flask KVSession is that Beaker will lazy load sessions, so if you don't read the session information, it won't make a connection to the database on every call. However, Beaker depends on SQLAlchemy which is going to be a larger module than simplekv module.
Unless that specific performance case is important, I would still go with Flask KVSession because of its slightly simpler API and smaller code base.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With