What's the purpose of Django setting ‘SECRET_KEY’?
Solution 1
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
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
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.
Related videos on Youtube
David542
Updated on November 23, 2020Comments
-
David542 over 3 years
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?
-
Jared Farrish over 12 yearsIf you have a secret key, and it's compromised and released to others, you have a problem. It doesn't matter if you're using Django or not.
-
tobych over 12 yearsBut what problem, exactly?
-
sberder about 11 yearsI did a thorough answer here (shameless plug)
-
kasperd almost 9 years@sberder Maybe you should write an answer to this question as well. I imagine you could do it much better than the accepted non-answer.
-
-
datenwolf almost 11 yearsWhy didn't they call it a salt then? ;)
-
Roshan Mathews almost 11 yearsThis is a guess, but I suppose it is easier to tell people "don't share your
SECRET_KEY
", as opposed to "yourSALT
is a secret key that you should keep to yourself." -
Travis Jensen almost 10 yearsThat distinction is very important. In cryptography, salts are not secret, but
SECRET_KEY
must be kept secure. The use of theSECRET_KEY
is much more akin to the use of a key in a signed hash such as HMAC (which, if performance wasn't a consideration, would probably be used instead). -
kasperd almost 9 yearsThis does not look like an answer to me. All you did was a single grep command without explaining what any of it does. Where is the answer to "what could happen if the key was compromised?"?
-
Linus_30 almost 6 yearsAlso since the SECRET_KEY is confidential, prefixing a SECRET to the key ensures that Django will encrypt/mask the values where ever needed.
-
Adam Parkin almost 6 years"and unique between all Django instances." -- does this imply if say I have 3 webservers running the same Django app behind a load balancer I should have 3 distinct
SECRET_KEY
settings? -
bignose almost 6 years@AdamParkin, that sounds like a good start for a new question, to get its own answer.
-
Adam Parkin almost 6 yearsGreat suggestion, done: stackoverflow.com/questions/51657422/…
-
Hassan Baig over 5 yearsUseful info regarding what happens if the
SECRET_KEY
is rotated. +1 -
Jamie Marshall over 3 years@TravisJensen - wouldn't salts not being secret defeat their purpose? It would be trivial to include a known salt in brute force attack along with a password hash dictionary.
-
Rik Schaaf over 3 years@JamieMarshall for a brute force attack yes, but that is not the reason why hashes are salted. Their purpose is to combat the use of rainbow tables, instead of having to brute force a hash. In that case, it doesn't matter that the salt is public, since you'd still need to fully brute-force the hash using that salt. And if you are using a hashing algorithm that is brute forcible like md5 for security, then you have other issues that have nothing to do with the salt being public.
-
Marat Mkhitaryan almost 3 yearsIt's not used for passwords. Passwords use random generated salt for each account and PKGF hash by default. But it's used for other stuff, like generating password reset link, etc.. github.com/django/django/blob/main/django/contrib/auth/… github.com/django/django/blob/main/django/contrib/auth/…