Fixed #31757 -- Adjusted system check for SECRET_KEY to warn about autogenerated default keys.
Thanks Nick Pope, René Fleschenberg, and Carlton Gibson for reviews.
This commit is contained in:
parent
721c95ba0b
commit
b7f500396e
|
@ -9,6 +9,7 @@ REFERRER_POLICY_VALUES = {
|
|||
'strict-origin-when-cross-origin', 'unsafe-url',
|
||||
}
|
||||
|
||||
SECRET_KEY_INSECURE_PREFIX = 'django-insecure-'
|
||||
SECRET_KEY_MIN_LENGTH = 50
|
||||
SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5
|
||||
|
||||
|
@ -68,12 +69,14 @@ W008 = Warning(
|
|||
)
|
||||
|
||||
W009 = Warning(
|
||||
"Your SECRET_KEY has less than %(min_length)s characters or less than "
|
||||
"%(min_unique_chars)s unique characters. Please generate a long and random "
|
||||
"SECRET_KEY, otherwise many of Django's security-critical features will be "
|
||||
"vulnerable to attack." % {
|
||||
"Your SECRET_KEY has less than %(min_length)s characters, less than "
|
||||
"%(min_unique_chars)s unique characters, or it's prefixed with "
|
||||
"'%(insecure_prefix)s' indicating that it was generated automatically by "
|
||||
"Django. Please generate a long and random SECRET_KEY, otherwise many of "
|
||||
"Django's security-critical features will be vulnerable to attack." % {
|
||||
'min_length': SECRET_KEY_MIN_LENGTH,
|
||||
'min_unique_chars': SECRET_KEY_MIN_UNIQUE_CHARACTERS,
|
||||
'insecure_prefix': SECRET_KEY_INSECURE_PREFIX,
|
||||
},
|
||||
id='security.W009',
|
||||
)
|
||||
|
@ -195,7 +198,8 @@ def check_secret_key(app_configs, **kwargs):
|
|||
else:
|
||||
passed_check = (
|
||||
len(set(secret_key)) >= SECRET_KEY_MIN_UNIQUE_CHARACTERS and
|
||||
len(secret_key) >= SECRET_KEY_MIN_LENGTH
|
||||
len(secret_key) >= SECRET_KEY_MIN_LENGTH and
|
||||
not secret_key.startswith(SECRET_KEY_INSECURE_PREFIX)
|
||||
)
|
||||
return [] if passed_check else [W009]
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.core.checks.security.base import SECRET_KEY_INSECURE_PREFIX
|
||||
from django.core.management.templates import TemplateCommand
|
||||
|
||||
from ..utils import get_random_secret_key
|
||||
|
@ -15,6 +16,6 @@ class Command(TemplateCommand):
|
|||
target = options.pop('directory')
|
||||
|
||||
# Create a random SECRET_KEY to put it in the main settings.
|
||||
options['secret_key'] = get_random_secret_key()
|
||||
options['secret_key'] = SECRET_KEY_INSECURE_PREFIX + get_random_secret_key()
|
||||
|
||||
super().handle('project', project_name, target, **options)
|
||||
|
|
|
@ -437,10 +437,11 @@ The following checks are run if you use the :option:`check --deploy` option:
|
|||
``True``. Unless your site should be available over both SSL and non-SSL
|
||||
connections, you may want to either set this setting to ``True`` or configure
|
||||
a load balancer or reverse-proxy server to redirect all connections to HTTPS.
|
||||
* **security.W009**: Your :setting:`SECRET_KEY` has less than 50 characters or
|
||||
less than 5 unique characters. Please generate a long and random
|
||||
``SECRET_KEY``, otherwise many of Django's security-critical features will be
|
||||
vulnerable to attack.
|
||||
* **security.W009**: Your :setting:`SECRET_KEY` has less than 50 characters,
|
||||
less than 5 unique characters, or it's prefixed with ``'django-insecure-'``
|
||||
indicating that it was generated automatically by Django. Please generate a
|
||||
long and random ``SECRET_KEY``, otherwise many of Django's security-critical
|
||||
features will be vulnerable to attack.
|
||||
* **security.W010**: You have :mod:`django.contrib.sessions` in your
|
||||
:setting:`INSTALLED_APPS` but you have not set
|
||||
:setting:`SESSION_COOKIE_SECURE` to ``True``. Using a secure-only session
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.conf import settings
|
||||
from django.core.checks.security import base, csrf, sessions
|
||||
from django.core.management.utils import get_random_secret_key
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
|
||||
|
@ -394,6 +395,12 @@ class CheckSecretKeyTest(SimpleTestCase):
|
|||
def test_none_secret_key(self):
|
||||
self.assertEqual(base.check_secret_key(None), [base.W009])
|
||||
|
||||
@override_settings(
|
||||
SECRET_KEY=base.SECRET_KEY_INSECURE_PREFIX + get_random_secret_key()
|
||||
)
|
||||
def test_insecure_secret_key(self):
|
||||
self.assertEqual(base.check_secret_key(None), [base.W009])
|
||||
|
||||
@override_settings(SECRET_KEY=('abcdefghijklmnopqrstuvwx' * 2) + 'a')
|
||||
def test_low_length_secret_key(self):
|
||||
self.assertEqual(len(settings.SECRET_KEY), base.SECRET_KEY_MIN_LENGTH - 1)
|
||||
|
|
Loading…
Reference in New Issue