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

1from plain.exceptions import ImproperlyConfigured 

2from plain.runtime import settings 

3 

4from .messages import Warning 

5from .registry import register 

6 

7SECRET_KEY_INSECURE_PREFIX = "plain-insecure-" 

8SECRET_KEY_MIN_LENGTH = 50 

9SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5 

10 

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) 

19 

20W025 = Warning(SECRET_KEY_WARNING_MSG, id="security.W025") 

21 

22 

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 ) 

29 

30 

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 ) 

49 

50 

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 

65 

66 

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 ) 

80 

81 

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 )