If you’re using sessions in your Flask application, you may have started off with a simple default configuration, setting up the session secret for the app. It may look something like this:app.secret_key = b'Y\xf1Xz\x00\xad|eQ\x80t \xca\x1a\x10K'
This is perfectly fine in a development environment, where you have no concern for hackers trying to manipulate sessions. However, when you deploy your site, if this key is publicly available anywhere (like github) then hackers would have the ability to use that key to create their own session cookies with valid signatures, without having to get them from your server. That means, among other potential security concerns, they could set their own data into the session – which is often used for user authentication. You don’t want people to be able to set whatever user id they want in their session, because that allows them to bypass the login and pretend to be anyone they want!
Therefore, any time you deploy a Flask app using sessions, you need a way to hide the session key. While there are various ways to do this, my preference is to use the python-dotenv package. Here are the steps:
1. Run pipenv install python-dotenv
2. In your .gitignore file at the top level of the project, add a line saying .env
3. Run python -c 'import secrets; print(secrets.token_hex())'
in your terminal, and copy the result. This will be your secret key!
4. Create a file called .env in your flask server directory
5. In that file, put SECRET_KEY=
and then paste the key you copied from the terminal. No spaces or quotes necessary. An example may look like SECRET_KEY=6050fb1f5f3d35b14484718c447b1424375a6bbd39150701c0ffb5db506eadb2
6. In whichever file app.secret_key
is being set (could likely be app.py or config.py) add from os import environ
and from dotenv import load_dotenv
7. Before your secret key is set, add this line load_dotenv('.env')
8. Finally, change the original line that was setting the secret key to app.secret_key = environ.get('SECRET_KEY')
When you start your server up, it will now load variables from the .env file into your environment, so that last line can pull the value out and use it for the secret_key every time! The only problem remaining is that usually when you deploy your application, you’ll be doing so with git – which is ignoring the .env file. Wherever you’re hosting your site, they will have other ways to set environment files though – either through running some commands in a terminal – or very often they have a place on their site allowing you to do some server configuration. All you need to do is set up a key called SECRET_KEY with a secret key value. It’s probably fine to use the same one in your .env file, but there’s no particular reason they need to be the same in production, and often it’s probably a better idea to generate a new one for the production server to use.
Note
If collaborating with others on a git repo, only 1 person needs to do all these steps – except for the creation of the .env file and setting the SECRET_KEY value in that file. Each person will have to make their own. It doesn’t matter if you all use the same key or not because your servers and session cookies will all be independent of each other during development anyway. Also – when other people do pull these changes – they will need to re-run pipenv install
in order to get the new dependency that was added.
Final Note
As you were following along you may have intuited that this technique can be used for other secret keys as well – like a 3rd party API private key. That’s right! All you have to do is add more lines to your .env file with the same sort of syntax as before, just different key names. Then in your application, you can use environ.get('WHATEVER_KEY_YOU_WANT')
to access the value stored there. Similarly, you’d need to set up an environment variable wherever you deploy, using their settings or whatever method they recommend.