Coverage for /Users/davegaeddert/Development/dropseed/plain/plain/plain/preflight/security/base.py: 54%
41 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-16 22:04 -0500
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-16 22:04 -0500
1from plain.exceptions import ImproperlyConfigured
2from plain.runtime import settings
4from .. import Warning, register
6SECRET_KEY_INSECURE_PREFIX = "plain-insecure-"
7SECRET_KEY_MIN_LENGTH = 50
8SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5
10SECRET_KEY_WARNING_MSG = (
11 f"Your %s has less than {SECRET_KEY_MIN_LENGTH} characters, less than "
12 f"{SECRET_KEY_MIN_UNIQUE_CHARACTERS} unique characters, or it's prefixed "
13 f"with '{SECRET_KEY_INSECURE_PREFIX}' indicating that it was generated "
14 f"automatically by Plain. Please generate a long and random value, "
15 f"otherwise many of Plain's security-critical features will be "
16 f"vulnerable to attack."
17)
19# TODO
20W001 = Warning(
21 "You do not have 'plain.middleware.https.HttpsRedirectMiddleware' "
22 "in your MIDDLEWARE so the SECURE_HSTS_SECONDS, "
23 "SECURE_CONTENT_TYPE_NOSNIFF, SECURE_REFERRER_POLICY, "
24 "SECURE_CROSS_ORIGIN_OPENER_POLICY, and HTTPS_REDIRECT_ENABLED settings will "
25 "have no effect.",
26 id="security.W001",
27)
29W008 = Warning(
30 "Your HTTPS_REDIRECT_ENABLED setting is not set to True. "
31 "Unless your site should be available over both SSL and non-SSL "
32 "connections, you may want to either set this setting True "
33 "or configure a load balancer or reverse-proxy server "
34 "to redirect all connections to HTTPS.",
35 id="security.W008",
36)
38W009 = Warning(
39 SECRET_KEY_WARNING_MSG % "SECRET_KEY",
40 id="security.W009",
41)
43W018 = Warning(
44 "You should not have DEBUG set to True in deployment.",
45 id="security.W018",
46)
48W020 = Warning(
49 "ALLOWED_HOSTS must not be empty in deployment.",
50 id="security.W020",
51)
53W025 = Warning(SECRET_KEY_WARNING_MSG, id="security.W025")
56def _check_secret_key(secret_key):
57 return (
58 len(set(secret_key)) >= SECRET_KEY_MIN_UNIQUE_CHARACTERS
59 and len(secret_key) >= SECRET_KEY_MIN_LENGTH
60 and not secret_key.startswith(SECRET_KEY_INSECURE_PREFIX)
61 )
64@register(deploy=True)
65def check_secret_key(package_configs, **kwargs):
66 try:
67 secret_key = settings.SECRET_KEY
68 except (ImproperlyConfigured, AttributeError):
69 passed_check = False
70 else:
71 passed_check = _check_secret_key(secret_key)
72 return [] if passed_check else [W009]
75@register(deploy=True)
76def check_secret_key_fallbacks(package_configs, **kwargs):
77 warnings = []
78 try:
79 fallbacks = settings.SECRET_KEY_FALLBACKS
80 except (ImproperlyConfigured, AttributeError):
81 warnings.append(Warning(W025.msg % "SECRET_KEY_FALLBACKS", id=W025.id))
82 else:
83 for index, key in enumerate(fallbacks):
84 if not _check_secret_key(key):
85 warnings.append(
86 Warning(W025.msg % f"SECRET_KEY_FALLBACKS[{index}]", id=W025.id)
87 )
88 return warnings
91@register(deploy=True)
92def check_debug(package_configs, **kwargs):
93 passed_check = not settings.DEBUG
94 return [] if passed_check else [W018]
97@register(deploy=True)
98def check_allowed_hosts(package_configs, **kwargs):
99 return [] if settings.ALLOWED_HOSTS else [W020]