You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

base.py 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. from django.conf import settings
  2. from .. import Tags, Warning, register
  3. SECRET_KEY_MIN_LENGTH = 50
  4. SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5
  5. W001 = Warning(
  6. "You do not have 'django.middleware.security.SecurityMiddleware' "
  7. "in your MIDDLEWARE so the SECURE_HSTS_SECONDS, "
  8. "SECURE_CONTENT_TYPE_NOSNIFF, "
  9. "SECURE_BROWSER_XSS_FILTER, and SECURE_SSL_REDIRECT settings "
  10. "will have no effect.",
  11. id='security.W001',
  12. )
  13. W002 = Warning(
  14. "You do not have "
  15. "'django.middleware.clickjacking.XFrameOptionsMiddleware' in your "
  16. "MIDDLEWARE, so your pages will not be served with an "
  17. "'x-frame-options' header. Unless there is a good reason for your "
  18. "site to be served in a frame, you should consider enabling this "
  19. "header to help prevent clickjacking attacks.",
  20. id='security.W002',
  21. )
  22. W004 = Warning(
  23. "You have not set a value for the SECURE_HSTS_SECONDS setting. "
  24. "If your entire site is served only over SSL, you may want to consider "
  25. "setting a value and enabling HTTP Strict Transport Security. "
  26. "Be sure to read the documentation first; enabling HSTS carelessly "
  27. "can cause serious, irreversible problems.",
  28. id='security.W004',
  29. )
  30. W005 = Warning(
  31. "You have not set the SECURE_HSTS_INCLUDE_SUBDOMAINS setting to True. "
  32. "Without this, your site is potentially vulnerable to attack "
  33. "via an insecure connection to a subdomain. Only set this to True if "
  34. "you are certain that all subdomains of your domain should be served "
  35. "exclusively via SSL.",
  36. id='security.W005',
  37. )
  38. W006 = Warning(
  39. "Your SECURE_CONTENT_TYPE_NOSNIFF setting is not set to True, "
  40. "so your pages will not be served with an "
  41. "'X-Content-Type-Options: nosniff' header. "
  42. "You should consider enabling this header to prevent the "
  43. "browser from identifying content types incorrectly.",
  44. id='security.W006',
  45. )
  46. W007 = Warning(
  47. "Your SECURE_BROWSER_XSS_FILTER setting is not set to True, "
  48. "so your pages will not be served with an "
  49. "'X-XSS-Protection: 1; mode=block' header. "
  50. "You should consider enabling this header to activate the "
  51. "browser's XSS filtering and help prevent XSS attacks.",
  52. id='security.W007',
  53. )
  54. W008 = Warning(
  55. "Your SECURE_SSL_REDIRECT setting is not set to True. "
  56. "Unless your site should be available over both SSL and non-SSL "
  57. "connections, you may want to either set this setting True "
  58. "or configure a load balancer or reverse-proxy server "
  59. "to redirect all connections to HTTPS.",
  60. id='security.W008',
  61. )
  62. W009 = Warning(
  63. "Your SECRET_KEY has less than %(min_length)s characters or less than "
  64. "%(min_unique_chars)s unique characters. Please generate a long and random "
  65. "SECRET_KEY, otherwise many of Django's security-critical features will be "
  66. "vulnerable to attack." % {
  67. 'min_length': SECRET_KEY_MIN_LENGTH,
  68. 'min_unique_chars': SECRET_KEY_MIN_UNIQUE_CHARACTERS,
  69. },
  70. id='security.W009',
  71. )
  72. W018 = Warning(
  73. "You should not have DEBUG set to True in deployment.",
  74. id='security.W018',
  75. )
  76. W019 = Warning(
  77. "You have "
  78. "'django.middleware.clickjacking.XFrameOptionsMiddleware' in your "
  79. "MIDDLEWARE, but X_FRAME_OPTIONS is not set to 'DENY'. "
  80. "The default is 'SAMEORIGIN', but unless there is a good reason for "
  81. "your site to serve other parts of itself in a frame, you should "
  82. "change it to 'DENY'.",
  83. id='security.W019',
  84. )
  85. W020 = Warning(
  86. "ALLOWED_HOSTS must not be empty in deployment.",
  87. id='security.W020',
  88. )
  89. W021 = Warning(
  90. "You have not set the SECURE_HSTS_PRELOAD setting to True. Without this, "
  91. "your site cannot be submitted to the browser preload list.",
  92. id='security.W021',
  93. )
  94. def _security_middleware():
  95. return 'django.middleware.security.SecurityMiddleware' in settings.MIDDLEWARE
  96. def _xframe_middleware():
  97. return 'django.middleware.clickjacking.XFrameOptionsMiddleware' in settings.MIDDLEWARE
  98. @register(Tags.security, deploy=True)
  99. def check_security_middleware(app_configs, **kwargs):
  100. passed_check = _security_middleware()
  101. return [] if passed_check else [W001]
  102. @register(Tags.security, deploy=True)
  103. def check_xframe_options_middleware(app_configs, **kwargs):
  104. passed_check = _xframe_middleware()
  105. return [] if passed_check else [W002]
  106. @register(Tags.security, deploy=True)
  107. def check_sts(app_configs, **kwargs):
  108. passed_check = not _security_middleware() or settings.SECURE_HSTS_SECONDS
  109. return [] if passed_check else [W004]
  110. @register(Tags.security, deploy=True)
  111. def check_sts_include_subdomains(app_configs, **kwargs):
  112. passed_check = (
  113. not _security_middleware() or
  114. not settings.SECURE_HSTS_SECONDS or
  115. settings.SECURE_HSTS_INCLUDE_SUBDOMAINS is True
  116. )
  117. return [] if passed_check else [W005]
  118. @register(Tags.security, deploy=True)
  119. def check_sts_preload(app_configs, **kwargs):
  120. passed_check = (
  121. not _security_middleware() or
  122. not settings.SECURE_HSTS_SECONDS or
  123. settings.SECURE_HSTS_PRELOAD is True
  124. )
  125. return [] if passed_check else [W021]
  126. @register(Tags.security, deploy=True)
  127. def check_content_type_nosniff(app_configs, **kwargs):
  128. passed_check = (
  129. not _security_middleware() or
  130. settings.SECURE_CONTENT_TYPE_NOSNIFF is True
  131. )
  132. return [] if passed_check else [W006]
  133. @register(Tags.security, deploy=True)
  134. def check_xss_filter(app_configs, **kwargs):
  135. passed_check = (
  136. not _security_middleware() or
  137. settings.SECURE_BROWSER_XSS_FILTER is True
  138. )
  139. return [] if passed_check else [W007]
  140. @register(Tags.security, deploy=True)
  141. def check_ssl_redirect(app_configs, **kwargs):
  142. passed_check = (
  143. not _security_middleware() or
  144. settings.SECURE_SSL_REDIRECT is True
  145. )
  146. return [] if passed_check else [W008]
  147. @register(Tags.security, deploy=True)
  148. def check_secret_key(app_configs, **kwargs):
  149. passed_check = (
  150. getattr(settings, 'SECRET_KEY', None) and
  151. len(set(settings.SECRET_KEY)) >= SECRET_KEY_MIN_UNIQUE_CHARACTERS and
  152. len(settings.SECRET_KEY) >= SECRET_KEY_MIN_LENGTH
  153. )
  154. return [] if passed_check else [W009]
  155. @register(Tags.security, deploy=True)
  156. def check_debug(app_configs, **kwargs):
  157. passed_check = not settings.DEBUG
  158. return [] if passed_check else [W018]
  159. @register(Tags.security, deploy=True)
  160. def check_xframe_deny(app_configs, **kwargs):
  161. passed_check = (
  162. not _xframe_middleware() or
  163. settings.X_FRAME_OPTIONS == 'DENY'
  164. )
  165. return [] if passed_check else [W019]
  166. @register(Tags.security, deploy=True)
  167. def check_allowed_hosts(app_configs, **kwargs):
  168. return [] if settings.ALLOWED_HOSTS else [W020]