Coverage for /Users/davegaeddert/Developer/dropseed/plain/plain/plain/preflight/security.py: 49%
37 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-23 11:16 -0600
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-23 11:16 -0600
1from plain.exceptions import ImproperlyConfigured
2from plain.runtime import settings
4from .messages import Warning
5from .registry import register
7SECRET_KEY_INSECURE_PREFIX = "plain-insecure-"
8SECRET_KEY_MIN_LENGTH = 50
9SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5
11SECRET_KEY_WARNING_MSG = (
12 f"Your %s has less than {SECRET_KEY_MIN_LENGTH} characters, less than "
13 f"{SECRET_KEY_MIN_UNIQUE_CHARACTERS} unique characters, or it's prefixed "
14 f"with '{SECRET_KEY_INSECURE_PREFIX}' indicating that it was generated "
15 f"automatically by Plain. Please generate a long and random value, "
16 f"otherwise many of Plain's security-critical features will be "
17 f"vulnerable to attack."
18)
20W025 = Warning(SECRET_KEY_WARNING_MSG, id="security.W025")
23def _check_secret_key(secret_key):
24 return (
25 len(set(secret_key)) >= SECRET_KEY_MIN_UNIQUE_CHARACTERS
26 and len(secret_key) >= SECRET_KEY_MIN_LENGTH
27 and not secret_key.startswith(SECRET_KEY_INSECURE_PREFIX)
28 )
31@register(deploy=True)
32def check_secret_key(package_configs, **kwargs):
33 try:
34 secret_key = settings.SECRET_KEY
35 except (ImproperlyConfigured, AttributeError):
36 passed_check = False
37 else:
38 passed_check = _check_secret_key(secret_key)
39 return (
40 []
41 if passed_check
42 else [
43 Warning(
44 SECRET_KEY_WARNING_MSG % "SECRET_KEY",
45 id="security.W009",
46 )
47 ]
48 )
51@register(deploy=True)
52def check_secret_key_fallbacks(package_configs, **kwargs):
53 warnings = []
54 try:
55 fallbacks = settings.SECRET_KEY_FALLBACKS
56 except (ImproperlyConfigured, AttributeError):
57 warnings.append(Warning(W025.msg % "SECRET_KEY_FALLBACKS", id=W025.id))
58 else:
59 for index, key in enumerate(fallbacks):
60 if not _check_secret_key(key):
61 warnings.append(
62 Warning(W025.msg % f"SECRET_KEY_FALLBACKS[{index}]", id=W025.id)
63 )
64 return warnings
67@register(deploy=True)
68def check_debug(package_configs, **kwargs):
69 passed_check = not settings.DEBUG
70 return (
71 []
72 if passed_check
73 else [
74 Warning(
75 "You should not have DEBUG set to True in deployment.",
76 id="security.W018",
77 )
78 ]
79 )
82@register(deploy=True)
83def check_allowed_hosts(package_configs, **kwargs):
84 return (
85 []
86 if settings.ALLOWED_HOSTS
87 else [
88 Warning(
89 "ALLOWED_HOSTS must not be empty in deployment.",
90 id="security.W020",
91 )
92 ]
93 )