Flask Python Redis Session Management Web Application Security

Prevent Session Replay Attack in Python Flask

Written by Ishan Girdhar

How to Prevent Session Replay Attack in Python Flask?

Everything was good until I found out that flask maintains only client side cookies which could lead to session replay attack. Flask cookies are secure as in, they cannot be tampered with as cookie is encrypted with a secret key which ensures only your application can read it.

But why does Flask maintains  client side cookies only?

Being a security engineer, it was very discomforting to know that my application is vulnerable to session replay attack and I had to do something about it.

Prevent Session Replay Attacks

So, I researched about how to use server side session in python flask app and it immediately directed me to a sample code on how to use redis for server side session management by Armin Ronacher and then this stackoverflow question revealed about Flask KV Session.

Flask KV-Session  is an MIT-licensed server-side session drop-in replacement for Flask‘s signed client-based session management. Instead of storing data on the client, only a securely generated ID is stored on the client, while the actual session data resides on the server. You can read more about Flask KV-Session here.

So, I went ahead with the instructions mentioned in the documentation:

Step 1: Install redis – I installed redis on Mac using Brew. If you want to install redis on on Ubuntu you can follow the tutorial here.

Step 2: Install redis for python using pip

Step 3: Start redis server:

Step 4: Add the following example code in your python application:

This is brilliant!! It just works with whatever I already have, I don’t need to change a single line of code for using this.

But I discovered that the session replay attack was still happening.

What you will see is that flask KV-Session is handling the session instead of flask itself, by creating a random id concatenating it with the timestamp and dropping it as a cookie value.

Flask-KVSession doc says:

Internally, Flask-KVSession stores session id’s that are serialized as
KEY_CREATED, where KEY is a random number (the sessions “true” id) and
CREATED a UNIX-timestamp of when the session was created.

You can confirm the same by checking the sample cookie value that gets created on the browser :

and session id stored in redis as key:

Since, we have not added any code on the logout handler, session cookies are not removed from redis. It will only be removed  when TTL will be turned to Zero (O).

Flask KV-Session by default have TTL Support for redis, it takes the TTL value from PERMANENT SESSION LIFETIME. So, for example if you have set that as 5 min, your redis “key” will also have TTL value of 5 min (300 Seconds).

In my application I have set PERMANENT SESSION LIFETIME in the beginning of app.py file as:

So, on logout handler, you just need to

  1. Read the cookie value
  2.  Split it and
  3. Use the first part of the string to delete the key-value pair from redis, as shown in the code below:
Now, when you will run this code, you will notice that it deletes the key in redis but it will not be removed until TTL for that turns to 0 from 300 (5 Min as mentioned in permanent_session_lifetime value ).

If you want to remove it from redis immediately then you will have to manually change the app.permanent_session_lifetime to 1 second, which will in turn change the TTL for redis,  as show in the code below:

By using the above code, cookies will be deleted immediately from redis.

Hence, I was successfully able to prevent the session replay attack.

If you do use this method or have any anything to add, I would love to hear about it in the comments below.

About the author

Ishan Girdhar

OSCP Certified, Infosec Consultant/Penetration Tester/Adrenaline Junkie/Influential Speaker/Pythoneer/traveler/Blogger/Social Engineer/Science Lover & husband.

  • Sameer

    Thats a nice article and helped preventing replay attack. So far so good.
    After adding this line to the code,
    app.permanent_session_lifetime = timedelta(seconds=1)

    all the other logged in users get logged out because permanent session time has reduced to 1 sec.
    Did you also face a similar issue?

    • Ishan Girdhar

      Yes, It will logout all users if you’re making this change in production. However, ideally this should be done during development when you’re writing and testing session management.

  • Thomas

    Hi, nice article which helped me a lot but I have a question. After loggin out I am not able to log in again because TTL has been set to 1 second. It only unsets when I completely restart the application.

    So how to prevend to have this change preventing anyone from logging in? Thanks in advance

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.