What's the purpose of Django setting ‘SECRET_KEY’?
I did a few google searches and checked out the docs ( https://docs.djangoproject.com/en/dev/ref/settings/#secret-key ), but I was looking for a more in-depth explanation of this, and why it is required.
For example, what could happen if the key was compromised / others knew what it was?
It is used for making hashes. Look:
>grep -Inr SECRET_KEY *
conf/global_settings.py:255:SECRET_KEY = ''
conf/project_template/settings.py:61:SECRET_KEY = ''
contrib/auth/tokens.py:54: hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) +
contrib/comments/forms.py:86: info = (content_type, object_pk, timestamp, settings.SECRET_KEY)
contrib/formtools/utils.py:15: order, pickles the result with the SECRET_KEY setting, then takes an md5
contrib/formtools/utils.py:32: data.append(settings.SECRET_KEY)
contrib/messages/storage/cookie.py:112: SECRET_KEY, modified to make it unique for the present purpose.
contrib/messages/storage/cookie.py:114: key = 'django.contrib.messages' + settings.SECRET_KEY
contrib/sessions/backends/base.py:89: pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
contrib/sessions/backends/base.py:95: if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
contrib/sessions/backends/base.py:134: # Use settings.SECRET_KEY as added salt.
contrib/sessions/backends/base.py:143: settings.SECRET_KEY)).hexdigest()
contrib/sessions/models.py:16: pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
contrib/sessions/models.py:59: if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
core/management/commands/startproject.py:32: # Create a random SECRET_KEY hash, and put it in the main settings.
core/management/commands/startproject.py:37: settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents)
middleware/csrf.py:38: % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
middleware/csrf.py:41: return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()
The Django documentation for cryptographic signing covers the uses of the ‘SECRET_KEY’ setting:
This value [the
SECRET_KEY
setting] is the key to securing signed data – it is vital you keep this secure, or attackers could use it to generate their own signed values.
(This section is also referenced from the Django documentation for the ‘SECRET_KEY’ setting.)
The cryptographic signing API in Django is available to any app for cryptographically-secure signatures on values. Django itself makes use of this in various higher-level features:
Signing serialised data (e.g. JSON documents).
Unique tokens for a user session, password reset request, messages, etc.
Prevention of cross-site or replay attacks by adding (and then expecting) unique values for the request.
Generating a unique salt for hash functions.
So, the general answer is: There are many things in a Django app which require a cryptographic signature, and the ‘SECRET_KEY’ setting is the key used for those. It needs to have a cryptographically strong amount of entropy (hard for computers to guess) and unique between all Django instances.
According to the Django Documentation on SECRET_KEY
:
The secret key is used for:
- All sessions if you are using any other session backend than
django.contrib.sessions.backends.cache
, or are using the defaultget_session_auth_hash()
.- All messages if you are using
CookieStorage
orFallbackStorage
.- All PasswordResetView tokens.
- Any usage of cryptographic signing, unless a different key is provided.
If you rotate your secret key, all of the above will be invalidated. Secret keys are not used for passwords of users and key rotation will not affect them.