Hiding Django's Secret Key
Posted on
by Miles Steele
Django uses a secret key for many of its security features. This secret key should not be checked into version control. There are many ways to factor out the secret key; here’s the one I use.
The secret key entry is stored by default in settings.py
:
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'y2k94mib_ve%c9hth=9grurdontuse1(t&his;jy-xkcd'
From the Django Docs:
Running Django with a known SECRET_KEY defeats many of Django’s security protections, and can lead to privilege escalation and remote code execution vulnerabilities.
In your settings.py
, replace the SECRET_KEY
entry with the following block of code. It will look for an existing secret key in and if it does not find one, then it will generate and save one into secret_key.py
when the settings file is used.
# SECURITY WARNING: keep the secret key used in production secret!
import sys
def find_or_create_secret_key():
"""
Look for secret_key.py and return the SECRET_KEY entry in it if the file exists.
Otherwise, generate a new secret key, save it in secret_key.py, and return the key.
"""
SECRET_KEY_DIR = os.path.dirname(__file__)
SECRET_KEY_FILEPATH = os.path.join(SECRET_KEY_DIR, 'secret_key.py')
sys.path.insert(1,SECRET_KEY_DIR)
if os.path.isfile(SECRET_KEY_FILEPATH):
from secret_key import SECRET_KEY
return SECRET_KEY
else:
from django.utils.crypto import get_random_string
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
new_key = get_random_string(50, chars)
with open(SECRET_KEY_FILEPATH, 'w') as f:
f.write("# Django secret key\n# Do NOT check this into version control.\n\nSECRET_KEY = '%s'\n" % new_key)
from secret_key import SECRET_KEY
return SECRET_KEY
# Make this unique, and don't share it with anybody.
SECRET_KEY = find_or_create_secret_key()
That’s it. Be sure to add secret_key.py
to your .gitignore
!