There's debate in #24994 about whether or not settings.SECRET_KEY should or 
may be a bytestring. Some select quotes to summarize the discussion:

1. Aymeric Augustin, "Once Django drops support for Python 2 you'll have to 
go out of your way to put bytes in the SECRET_KEY.

Currently, since the type isn't enforced, every app that wants to do 
something with SECRET_KEY should conditionally convert it to bytes, 
typically with force_bytes, since it _could_ be bytes. I don't think this 
is common knowledge; it's even a pitfall.

Enforcing the type would simplify that code and avoid errors for the 
minority who uses bytes in pluggable apps that assume text e.g. by doing 
settings.SECRET_KEY.encode()."

2. Andres Mejia, " Cryptographic keys are suppose to be random bytes that 
don't necessarily represent a Unicode string. See also the RFC I linked in 
my comment.

I think it's fair to assume devs using the SECRET_KEY know it must be used 
as bytes. Various crypto libraries will refuse to accept them otherwise. 
This is true of the hmac, cryptography, and pyOpenSSL libraries.

As for my use case, a common practice is to use an external script or 
program to pipe secrets into processes that need them. I use something like 
this to not only setup my Django sites but to also rotate the secrets in 
them whenever necessary. The output from a subprocess.check_output() call 
is in bytes. As of now, since Django accepts the SECRET_KEY as bytes, I use 
random bytes for my SECRET_KEY and have it loaded in my Django sites via an 
external program."

-----

A past issue, #19980, noted that Signer was broken when SECRET_KEY contains 
non-ASCII bytes and it was fixed.

1. Claude Paroz, "The random string that Django produces in startproject 
never contains non-ascii characters. Now of course anyone is free to set it 
to any random content. However, do we gain anything in allowing SECRET_KEY 
to be a bytestring? In the spirit of Python 3, I would be more in favour of 
documenting that SECRET_KEY is a string (not a bytestring), and if you 
include in it any non-ASCII chars on Python 2, you should prefix it by u''."

2. Anonymous, "I would argue that, given that this is used in cryptographic 
contexts, the key should be bytes, not a string. At the lowest level, all 
crypto happens on bytes anyway, and with strings you always rely on an 
encoding. Even though we can assume utf-8 fairly reasonably, this still is 
an assumption, and basically only used to convert the unicode string to a 
byte string. Why then, let us not pass in the bytes explicitly, independent 
of an encoding?
Even more so, this would make it similar to other web frameworks. For 
example, in Flask, the SECRET_KEY value is recommended to be generated 
completely random, using os.urandom(). Thus, a byte string.
If consensus is around using a unicode string nonetheless, this should be 
explicitly documented at the very least, and maybe even type-checked."

3. Luke Plant, "I agree it makes more sense for SECRET_KEY to be a 
bytestring, especially with the argument about os.random but we also need 
compatibility with unicode, especially as we cross the Python 2/3 barrier 
and as projects migrate.
So I think we should document that it can be either a string or bytestring, 
and it will be converted using UTF8 if it is a string."

4. Alex Gaynor, " in principle both the secret key and the salt_key should 
be bytes, not strings, so there should be no need to encode them."
-----

#24994 proposes to add a system check to disallow (or warn that it isn't 
proper) a SECRET_KEY that contains non-ASCII bytes (i.e. the case that was 
fixed in Signer in #19980).

I hope we can come to a decision and at least clarify the documentation. 
Perhaps deferring a code change (if any) until Django 2.0 so that only 
Python 3 is a consideration would help.

https://code.djangoproject.com/ticket/24994
https://code.djangoproject.com/ticket/19980

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/4da9423b-47db-40d3-bb95-2fa218256b50%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
  • Sho... Tim Graham
    • ... Ryan Hiebert
      • ... Tim Graham
        • ... Ryan Hiebert
    • ... Aymeric Augustin
      • ... Adam Johnson
        • ... Ryan Hiebert
          • ... Tim Graham
            • ... Aymeric Augustin
      • ... 'Andres Mejia' via Django developers (Contributions to Django itself)
        • ... Aymeric Augustin

Reply via email to