I am pretty new to web development. I am working with Flask, Sqlalchemy and Postgresql.
As far as I have understood, every new request is like a new thread of the program. New sqlalchemy session is created using which we manage our db operations and return a response. After that new thread is also closed and connections returned to the pool.
I login a user and get all user data in an user orm object. I stored it in flask session variable which uses cookie. Now I also want to save some other user related data for the span of whole user session not a request. I have doubts storing all that data in a cookie for 2 reasons:
1. Unnecessary data travel back and forth.
2. data can be read easily.
Are my doubts valid?
So my other questions are :
Am I right on some level to avoid getting some session wide data in each request without getting into the trap of premature optimization?
or
Should I worry about this later when need arises and right now concentrate only on creating a working app?
Alternative to cookie based session is server side session which can be done by using redis or memcache. Where does Beaker library comes into this? Is it a standalone thing or to be used in conjunction with redis or memcache?
Most browsers support cookies of up to 4096 bytes. (Source)
If you want to save more than this than you should use a server-side session backend like Redis or Memcache. It's very easy to replace the default cookie session interface of Flask with a Redis or Memcache interface. There is a great snippet for redis by Armin. If you prefere memcache than you can replace the redis stuff of the snippet with the same memcache methods. ;)
Related
When using the SignedCookieSessionFactory, the documentation states that the sha512 HMAC digest algorithm is used. As a result of this, once session data is serialised, it is signed and sent to the user's client under the session cookie.
There is no mention in Pyramid's documentation that sessions are also cached server-side (under this SessionFactory).
This presents a contradiction and has also led to authentication confusion when paired with SessionAuthenticationPolicy. If session data cannot be retrieved from the client's session cookie (as it is one-way hashed), how is it that the following is possible?
Authenticate with the application such that reading Request.authenticated_userid does not return None.
Copy the session cookie to the clipboard.
Logout by accessing a view whereby the headers from forget(request) are returned in the Response.
Replace the session cookie with the copied value.
The user is now logged back in.
I understand that simply deleting the cookie client-side is insufficient to completely invalidate the session (without blacklisting), but this then poses the following questions:
How is it possible to remain secure with browser-scoped sessions unless every session cookie the user has recently been issued is somehow remembered and blacklisted/invalidated?
Is the session cookie actually a key/session ID that's being used to lookup a session in memory? As it's one-way signed, surely this is the only explanation?
Is it possible then to invalidate sessions server-side, a little more robust than just the headers=forget(request) pattern?
Ultimately, I imagine the answer is something along the lines of:
"Maintain server-side sessions using an include such as pyramid_redis_sessions"
Any explanation would be appreciated.
The cookie contains all of the data. The session content itself is stored in the cookie, alongside an hmac signature of that content. This means that a client may view the content if they try hard enough, but they cannot change it as they cannot create trusted signatures without the server-side secret.
How is it possible to remain secure with browser-scoped sessions unless every session cookie the user has recently been issued is somehow remembered and blacklisted/invalidated?
It depends what you're using the session for - you need to take these issues into consideration before putting data into a session object.
Is it possible then to invalidate sessions server-side, a little more robust than just the headers=forget(request) pattern?
Not unless you store some sort of id in the session and then a server-side table of blacklisted ids. If you did this then you could write your own wrapper session-factory that opened the session, checked the id, and returned an empty one if it was blacklisted. Of course then you might just want to use a server-side session library like pyramid_redis_sessions or pyramid_beaker with one of its server-side-storage backends.
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?
The background
Method #1
An easy and safe way to handle sessions is to do the following:
Use a session cookie that contains a session ID (a random number).
Sign that session cookie using a secret key (to prevent tempering — this is what itsdangerous does).
Store actual session data in a database on the server side (index by ID, or use a NoSQL key / value store).
When a user accesses your page, you read the data from the database.
When a user logs out, you delete the data from the database.
Note that there are a few drawbacks.
You need to maintain that database backend (more maintenance)
You need to hit the database for every request (less performance)
Method #2
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:
This is easier on the backend (less maintenance, better performance).
You need to be careful to not include data your users should not see in sessions (unless you're encrypting).
The volume of data you can save in a cookie is limited.
You can't invalidate an individual session (!).
The code
Flask actually implements signed session cookies already, so it implements method #2.
To get from #2 to #1, all you have to do is:
Generate random Session IDs (you could use os.urandom + base64).
Save session data in a database backend, indexed by Session ID (serialize it using e.g. JSON, Picke if you need Python objects, but avoid if you can).
Delete sessions from your database backend when a user logs out.
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.
I have a problem and can't solve it. Maybe I'm making it too hard or complex or I'm just going in the wrong direction and thinking of things that don't make sense. Below is a description of what happens. (Multiple tabs opened in a browser or a page that requests some other pages at the same time for example.)
I have a situation where 3 requests are received by the web application simultaneously and new user session has to be created. This session is used to store notification, XSRF token and login information when the user logs in. The application uses threads to handle requests (CherryPy under Bottle.py).
The 3 threads (or processes in case or multiple application instances) start handling the 3 requests. They check the cookie, no session exists, and create a new unique token that is stored in a cookie and in Redis. This will all happen at the same time and they don't know if a session already has been created by another thread, because all 3 tokens are unique.
These unused sessions will expire eventually, but it's not neat. It means everytime a client simultaneously does N requests and a new session needs to be created, N-1 session are useless.
If there is a property that can be used to identify a client, like an IP address, it would be a lot easier, but an IP address is not safe to use in this case. This property can be used to atomically store a session in Redis and other requests would just pick up that session.
If this is through a browser and is using cookies then this shouldn't be an issue at all. The cookie will, from what I can tell, the last session value that it is set to. If the client you are using does not use cookies then of course it will open a new session for each connection.
I am currently working on an application for Google App Engine, and I need some advice to detect the number of online users in the application. How can I do this?
I am using a session library. Do I need to overwrite the session methods (create_session, destroy_session increment/and decrement a value in datastore) or is there another method that I can use?
HTTP is stateless, so there's no inherent definition of "online user". You could count the number of non-destroyed sessions you've created, but unless you've got a cron job that destroys old sessions, this won't give an accurate picture.
You basically need to decide how much time without a new page request counts as "online" and query for the sessions that have been updated in that range of time.
You may use channel api to maintain a connection with the client. "The Channel API creates a persistent connection between your application and Google servers, allowing your application to send messages to JavaScript clients in real time without the use of polling. "
http://code.google.com/appengine/docs/java/channel/overview.html
I'm using CherryPy to make a web-based frontend for SymPy that uses an asynchronous process library on the server side to allow for processing multiple requests at once without waiting for each one to complete. So as to allow for the frontend to function as expected, I am using one process for the entirety of each session. The client-side Javascript sends the session-id from the cookie to the server when the user submits a request, and the server-side currently uses a pair of lists, storing instances of a controller class in one and the corresponding session-id's in another, creating a new interpreter proxy and sending the input if a non-existant session-id is submitted. The only problem with this is that the proxy classes are not deleted upon the expiration of their corresponding sessions. Also, I can't see anything to retrieve the session-id for which the current request is being served.
My questions about all this are: is there any way to "connect" an arbitrary object to a CherryPy session so that it gets deleted upon session expiration, is there something I am overlooking here that would greatly simplify things, and does CherryPy's multi-threading negate the problem of synchronous reading of the stdout filehandle from the child process?
You can create your own session type, derived from CherryPy's base session. Use its clean_up method to do your cleanup.
Look at cherrypy/lib/sessions.py for details and sample session implementations.