What's the purpose of Django setting ‘SECRET_KEY’?
PythonDjangoSecurityEncryptionPython Problem Overview
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?
Python Solutions
Solution 1 - Python
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()
Solution 2 - Python
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.
Solution 3 - Python
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.