What's the purpose of Django setting ‘SECRET_KEY’?

93,239

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 default get_session_auth_hash().
  • All messages if you are using CookieStorage or FallbackStorage.
  • 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.

Share:
93,239

Related videos on Youtube

David542
Author by

David542

Updated on November 23, 2020

Comments

  • David542
    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
      Jared Farrish over 12 years
      If 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
      tobych over 12 years
      But what problem, exactly?
    • sberder
      sberder about 11 years
      I did a thorough answer here (shameless plug)
    • kasperd
      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
    datenwolf almost 11 years
    Why didn't they call it a salt then? ;)
  • Roshan Mathews
    Roshan Mathews almost 11 years
    This is a guess, but I suppose it is easier to tell people "don't share your SECRET_KEY", as opposed to "your SALT is a secret key that you should keep to yourself."
  • Travis Jensen
    Travis Jensen almost 10 years
    That distinction is very important. In cryptography, salts are not secret, but SECRET_KEY must be kept secure. The use of the SECRET_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
    kasperd almost 9 years
    This 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
    Linus_30 almost 6 years
    Also 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
    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
    bignose almost 6 years
    @AdamParkin, that sounds like a good start for a new question, to get its own answer.
  • Adam Parkin
    Adam Parkin almost 6 years
  • Hassan Baig
    Hassan Baig over 5 years
    Useful info regarding what happens if the SECRET_KEY is rotated. +1
  • Jamie Marshall
    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
    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
    Marat Mkhitaryan almost 3 years
    It'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/…