We’re looking at our session management on our project, and are exploring ways to make our platform more secure. We are exploring how to balance out the user experience with the risk of session highjacking. Shortening session duration is a good way to mitigate this risk, but past a certain point, it can degrade the user experience if e.g. users have to login too often.
Our system has -broadly speaking- 4 kind of users with more or less privileges:
- Internal staff with access to a broad range of actions, across multiple organisations (our clients), also gets access to the Django admin.
- Organisation admin: users in our clients org, they get more permissions like user management, etc… but are limited to the data within their org.
- Regular users: can perform a limited set of actions, all within their orgs
- Anonymous users: can only do a very limited set of actions, on some very specific pages
As we can see, the risk profile of each user type is different, and it would be an order of magnitude worse if a security issue happened with a session from an internal staff vs a regular user. And in terms of UX, we can afford to be more aggressive with internal users vs external ones.
We had the idea of implementing a dynamic session timeout based on the type of user: internal staff would have a timeout of something short like ~15mins, regular users could be a few hours/1 day, while anonymous users could be much longer sessions.
I looked into the current Django implementation, and from what I can see, it doesn’t seem easily feasible in the current state of things as the expiry is obtained in the SessionMiddleware:
max_age = request.session.get_expiry_age()
I was thinking to change this line to pass the request down:
max_age = request.session.get_expiry_age(request)
And then implement my own logic by subclassing Session and overriding get_session_cookie_age. However, doing so currently requires (I think) to copy the 55 lines long SessionMiddleware.process_response and change that single line.
Did I miss anything? Is there a simpler way to do what I want to do? Is there an appetite to change this request.session.get_expiry_age() line in the middleware in Django? Is there interest in making session expiry more dynamic in general?