2014-09-13 02:50:36 +08:00
|
|
|
from django.conf import settings
|
2021-12-14 11:47:03 +08:00
|
|
|
from django.core.checks.messages import Error, Warning
|
2015-01-28 20:35:27 +08:00
|
|
|
from django.core.checks.security import base, csrf, sessions
|
2020-07-14 01:40:38 +08:00
|
|
|
from django.core.management.utils import get_random_secret_key
|
2015-04-18 05:38:20 +08:00
|
|
|
from django.test import SimpleTestCase
|
2014-09-13 02:50:36 +08:00
|
|
|
from django.test.utils import override_settings
|
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckSessionCookieSecureTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_SECURE=False,
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=[],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_secure_with_installed_app(self):
|
|
|
|
"""
|
|
|
|
Warn if SESSION_COOKIE_SECURE is off and "django.contrib.sessions" is
|
|
|
|
in INSTALLED_APPS.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_secure(None), [sessions.W010])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2022-02-21 14:54:47 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_SECURE="1",
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
|
|
|
MIDDLEWARE=[],
|
|
|
|
)
|
|
|
|
def test_session_cookie_secure_with_installed_app_truthy(self):
|
|
|
|
"""SESSION_COOKIE_SECURE must be boolean."""
|
|
|
|
self.assertEqual(sessions.check_session_cookie_secure(None), [sessions.W010])
|
|
|
|
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_SECURE=False,
|
|
|
|
INSTALLED_APPS=[],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=["django.contrib.sessions.middleware.SessionMiddleware"],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_secure_with_middleware(self):
|
|
|
|
"""
|
|
|
|
Warn if SESSION_COOKIE_SECURE is off and
|
|
|
|
"django.contrib.sessions.middleware.SessionMiddleware" is in
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE.
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_secure(None), [sessions.W011])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2015-11-07 23:12:37 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_SECURE=False,
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=["django.contrib.sessions.middleware.SessionMiddleware"],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_secure_both(self):
|
|
|
|
"""
|
|
|
|
If SESSION_COOKIE_SECURE is off and we find both the session app and
|
|
|
|
the middleware, provide one common warning.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_secure(None), [sessions.W012])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2015-11-07 23:12:37 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_SECURE=True,
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=["django.contrib.sessions.middleware.SessionMiddleware"],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_secure_true(self):
|
|
|
|
"""
|
|
|
|
If SESSION_COOKIE_SECURE is on, there's no warning about it.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_secure(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckSessionCookieHttpOnlyTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_HTTPONLY=False,
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=[],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_httponly_with_installed_app(self):
|
|
|
|
"""
|
|
|
|
Warn if SESSION_COOKIE_HTTPONLY is off and "django.contrib.sessions"
|
|
|
|
is in INSTALLED_APPS.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_httponly(None), [sessions.W013])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2022-02-21 14:54:47 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_HTTPONLY="1",
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
|
|
|
MIDDLEWARE=[],
|
|
|
|
)
|
|
|
|
def test_session_cookie_httponly_with_installed_app_truthy(self):
|
|
|
|
"""SESSION_COOKIE_HTTPONLY must be boolean."""
|
|
|
|
self.assertEqual(sessions.check_session_cookie_httponly(None), [sessions.W013])
|
|
|
|
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_HTTPONLY=False,
|
|
|
|
INSTALLED_APPS=[],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=["django.contrib.sessions.middleware.SessionMiddleware"],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_httponly_with_middleware(self):
|
|
|
|
"""
|
|
|
|
Warn if SESSION_COOKIE_HTTPONLY is off and
|
|
|
|
"django.contrib.sessions.middleware.SessionMiddleware" is in
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE.
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_httponly(None), [sessions.W014])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_HTTPONLY=False,
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=["django.contrib.sessions.middleware.SessionMiddleware"],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_httponly_both(self):
|
|
|
|
"""
|
|
|
|
If SESSION_COOKIE_HTTPONLY is off and we find both the session app and
|
|
|
|
the middleware, provide one common warning.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_httponly(None), [sessions.W015])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
SESSION_COOKIE_HTTPONLY=True,
|
|
|
|
INSTALLED_APPS=["django.contrib.sessions"],
|
2018-03-16 17:54:34 +08:00
|
|
|
MIDDLEWARE=["django.contrib.sessions.middleware.SessionMiddleware"],
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_session_cookie_httponly_true(self):
|
|
|
|
"""
|
|
|
|
If SESSION_COOKIE_HTTPONLY is on, there's no warning about it.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(sessions.check_session_cookie_httponly(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckCSRFMiddlewareTest(SimpleTestCase):
|
2017-01-01 02:24:00 +08:00
|
|
|
@override_settings(MIDDLEWARE=[])
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_csrf_middleware(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
Warn if CsrfViewMiddleware isn't in MIDDLEWARE.
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(csrf.check_csrf_middleware(None), [csrf.W003])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2018-03-16 17:54:34 +08:00
|
|
|
@override_settings(MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"])
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_csrf_middleware(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(csrf.check_csrf_middleware(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckCSRFCookieSecureTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
CSRF_COOKIE_SECURE=False,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_csrf_cookie_secure_false(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
Warn if CsrfViewMiddleware is in MIDDLEWARE but
|
2014-09-13 02:50:36 +08:00
|
|
|
CSRF_COOKIE_SECURE isn't True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(csrf.check_csrf_cookie_secure(None), [csrf.W016])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2022-02-21 14:54:47 +08:00
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"],
|
|
|
|
CSRF_COOKIE_SECURE="1",
|
|
|
|
)
|
|
|
|
def test_with_csrf_cookie_secure_truthy(self):
|
|
|
|
"""CSRF_COOKIE_SECURE must be boolean."""
|
|
|
|
self.assertEqual(csrf.check_csrf_cookie_secure(None), [csrf.W016])
|
|
|
|
|
2016-12-17 22:59:48 +08:00
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"],
|
|
|
|
CSRF_USE_SESSIONS=True,
|
2018-03-16 17:54:34 +08:00
|
|
|
CSRF_COOKIE_SECURE=False,
|
|
|
|
)
|
2016-12-17 22:59:48 +08:00
|
|
|
def test_use_sessions_with_csrf_cookie_secure_false(self):
|
|
|
|
"""
|
|
|
|
No warning if CSRF_COOKIE_SECURE isn't True while CSRF_USE_SESSIONS
|
|
|
|
is True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(csrf.check_csrf_cookie_secure(None), [])
|
2016-12-17 22:59:48 +08:00
|
|
|
|
2017-01-01 02:24:00 +08:00
|
|
|
@override_settings(MIDDLEWARE=[], CSRF_COOKIE_SECURE=False)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_csrf_cookie_secure_false_no_middleware(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
No warning if CsrfViewMiddleware isn't in MIDDLEWARE, even if
|
2014-09-13 02:50:36 +08:00
|
|
|
CSRF_COOKIE_SECURE is False.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(csrf.check_csrf_cookie_secure(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
CSRF_COOKIE_SECURE=True,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_csrf_cookie_secure_true(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(csrf.check_csrf_cookie_secure(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckSecurityMiddlewareTest(SimpleTestCase):
|
2015-11-07 23:12:37 +08:00
|
|
|
@override_settings(MIDDLEWARE=[])
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_security_middleware(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
Warn if SecurityMiddleware isn't in MIDDLEWARE.
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_security_middleware(None), [base.W001])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2018-03-16 17:54:34 +08:00
|
|
|
@override_settings(MIDDLEWARE=["django.middleware.security.SecurityMiddleware"])
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_security_middleware(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_security_middleware(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckStrictTransportSecurityTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_HSTS_SECONDS=0,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_sts(self):
|
|
|
|
"""
|
|
|
|
Warn if SECURE_HSTS_SECONDS isn't > 0.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts(None), [base.W004])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2018-03-16 17:54:34 +08:00
|
|
|
@override_settings(MIDDLEWARE=[], SECURE_HSTS_SECONDS=0)
|
2015-12-03 07:55:50 +08:00
|
|
|
def test_no_sts_no_middleware(self):
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
|
|
|
Don't warn if SECURE_HSTS_SECONDS isn't > 0 and SecurityMiddleware isn't
|
|
|
|
installed.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_HSTS_SECONDS=3600,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_sts(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckStrictTransportSecuritySubdomainsTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2014-09-13 02:50:36 +08:00
|
|
|
SECURE_HSTS_INCLUDE_SUBDOMAINS=False,
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_HSTS_SECONDS=3600,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_sts_subdomains(self):
|
|
|
|
"""
|
|
|
|
Warn if SECURE_HSTS_INCLUDE_SUBDOMAINS isn't True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_include_subdomains(None), [base.W005])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=[],
|
2014-09-13 02:50:36 +08:00
|
|
|
SECURE_HSTS_INCLUDE_SUBDOMAINS=False,
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_HSTS_SECONDS=3600,
|
|
|
|
)
|
2015-12-03 07:55:50 +08:00
|
|
|
def test_no_sts_subdomains_no_middleware(self):
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
|
|
|
Don't warn if SecurityMiddleware isn't installed.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_include_subdomains(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2014-09-13 02:50:36 +08:00
|
|
|
SECURE_SSL_REDIRECT=False,
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_HSTS_SECONDS=None,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_sts_subdomains_no_seconds(self):
|
|
|
|
"""
|
|
|
|
Don't warn if SECURE_HSTS_SECONDS isn't set.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_include_subdomains(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2014-09-13 02:50:36 +08:00
|
|
|
SECURE_HSTS_INCLUDE_SUBDOMAINS=True,
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_HSTS_SECONDS=3600,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_sts_subdomains(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_include_subdomains(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2016-07-26 20:05:27 +08:00
|
|
|
class CheckStrictTransportSecurityPreloadTest(SimpleTestCase):
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_HSTS_PRELOAD=False,
|
|
|
|
SECURE_HSTS_SECONDS=3600,
|
|
|
|
)
|
|
|
|
def test_no_sts_preload(self):
|
|
|
|
"""
|
|
|
|
Warn if SECURE_HSTS_PRELOAD isn't True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_preload(None), [base.W021])
|
2016-07-26 20:05:27 +08:00
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=[], SECURE_HSTS_PRELOAD=False, SECURE_HSTS_SECONDS=3600
|
|
|
|
)
|
|
|
|
def test_no_sts_preload_no_middleware(self):
|
|
|
|
"""
|
|
|
|
Don't warn if SecurityMiddleware isn't installed.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_preload(None), [])
|
2016-07-26 20:05:27 +08:00
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_SSL_REDIRECT=False,
|
|
|
|
SECURE_HSTS_SECONDS=None,
|
|
|
|
)
|
|
|
|
def test_no_sts_preload_no_seconds(self):
|
|
|
|
"""
|
|
|
|
Don't warn if SECURE_HSTS_SECONDS isn't set.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_preload(None), [])
|
2016-07-26 20:05:27 +08:00
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_HSTS_PRELOAD=True,
|
|
|
|
SECURE_HSTS_SECONDS=3600,
|
|
|
|
)
|
|
|
|
def test_with_sts_preload(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_sts_preload(None), [])
|
2016-07-26 20:05:27 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckXFrameOptionsMiddlewareTest(SimpleTestCase):
|
2015-11-07 23:12:37 +08:00
|
|
|
@override_settings(MIDDLEWARE=[])
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_middleware_not_installed(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
Warn if XFrameOptionsMiddleware isn't in MIDDLEWARE.
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_xframe_options_middleware(None), [base.W002])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2015-11-07 23:12:37 +08:00
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.clickjacking.XFrameOptionsMiddleware"]
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_middleware_installed(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_xframe_options_middleware(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckXFrameOptionsDenyTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.clickjacking.XFrameOptionsMiddleware"],
|
2014-09-13 02:50:36 +08:00
|
|
|
X_FRAME_OPTIONS="SAMEORIGIN",
|
|
|
|
)
|
|
|
|
def test_x_frame_options_not_deny(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
Warn if XFrameOptionsMiddleware is in MIDDLEWARE but
|
2014-09-13 02:50:36 +08:00
|
|
|
X_FRAME_OPTIONS isn't 'DENY'.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_xframe_deny(None), [base.W019])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2015-11-07 23:12:37 +08:00
|
|
|
@override_settings(MIDDLEWARE=[], X_FRAME_OPTIONS="SAMEORIGIN")
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_middleware_not_installed(self):
|
|
|
|
"""
|
2015-11-07 23:12:37 +08:00
|
|
|
No error if XFrameOptionsMiddleware isn't in MIDDLEWARE even if
|
2014-09-13 02:50:36 +08:00
|
|
|
X_FRAME_OPTIONS isn't 'DENY'.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_xframe_deny(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.clickjacking.XFrameOptionsMiddleware"],
|
2014-09-13 02:50:36 +08:00
|
|
|
X_FRAME_OPTIONS="DENY",
|
|
|
|
)
|
|
|
|
def test_xframe_deny(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_xframe_deny(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckContentTypeNosniffTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_CONTENT_TYPE_NOSNIFF=False,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_content_type_nosniff(self):
|
|
|
|
"""
|
|
|
|
Warn if SECURE_CONTENT_TYPE_NOSNIFF isn't True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_content_type_nosniff(None), [base.W006])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2018-03-16 17:54:34 +08:00
|
|
|
@override_settings(MIDDLEWARE=[], SECURE_CONTENT_TYPE_NOSNIFF=False)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_content_type_nosniff_no_middleware(self):
|
|
|
|
"""
|
|
|
|
Don't warn if SECURE_CONTENT_TYPE_NOSNIFF isn't True and
|
2015-11-07 23:12:37 +08:00
|
|
|
SecurityMiddleware isn't in MIDDLEWARE.
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_content_type_nosniff(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_CONTENT_TYPE_NOSNIFF=True,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_content_type_nosniff(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_content_type_nosniff(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckSSLRedirectTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_SSL_REDIRECT=False,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_no_ssl_redirect(self):
|
|
|
|
"""
|
|
|
|
Warn if SECURE_SSL_REDIRECT isn't True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_ssl_redirect(None), [base.W008])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2018-03-16 17:54:34 +08:00
|
|
|
@override_settings(MIDDLEWARE=[], SECURE_SSL_REDIRECT=False)
|
2015-12-03 07:55:50 +08:00
|
|
|
def test_no_ssl_redirect_no_middleware(self):
|
2014-09-13 02:50:36 +08:00
|
|
|
"""
|
|
|
|
Don't warn if SECURE_SSL_REDIRECT is False and SecurityMiddleware isn't
|
|
|
|
installed.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_ssl_redirect(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(
|
2015-11-07 23:12:37 +08:00
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
2018-03-16 17:54:34 +08:00
|
|
|
SECURE_SSL_REDIRECT=True,
|
|
|
|
)
|
2014-09-13 02:50:36 +08:00
|
|
|
def test_with_ssl_redirect(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_ssl_redirect(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckSecretKeyTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(SECRET_KEY=("abcdefghijklmnopqrstuvwx" * 2) + "ab")
|
|
|
|
def test_okay_secret_key(self):
|
|
|
|
self.assertEqual(len(settings.SECRET_KEY), base.SECRET_KEY_MIN_LENGTH)
|
|
|
|
self.assertGreater(
|
|
|
|
len(set(settings.SECRET_KEY)), base.SECRET_KEY_MIN_UNIQUE_CHARACTERS
|
|
|
|
)
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_secret_key(None), [])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(SECRET_KEY="")
|
|
|
|
def test_empty_secret_key(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_secret_key(None), [base.W009])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(SECRET_KEY=None)
|
|
|
|
def test_missing_secret_key(self):
|
|
|
|
del settings.SECRET_KEY
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_secret_key(None), [base.W009])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(SECRET_KEY=None)
|
|
|
|
def test_none_secret_key(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_secret_key(None), [base.W009])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
2020-07-14 01:40:38 +08:00
|
|
|
@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])
|
|
|
|
|
2014-09-13 02:50:36 +08:00
|
|
|
@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)
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_secret_key(None), [base.W009])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(SECRET_KEY="abcd" * 20)
|
|
|
|
def test_low_entropy_secret_key(self):
|
|
|
|
self.assertGreater(len(settings.SECRET_KEY), base.SECRET_KEY_MIN_LENGTH)
|
|
|
|
self.assertLess(
|
|
|
|
len(set(settings.SECRET_KEY)), base.SECRET_KEY_MIN_UNIQUE_CHARACTERS
|
|
|
|
)
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_secret_key(None), [base.W009])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
|
2021-12-14 11:47:03 +08:00
|
|
|
class CheckSecretKeyFallbacksTest(SimpleTestCase):
|
|
|
|
@override_settings(SECRET_KEY_FALLBACKS=[("abcdefghijklmnopqrstuvwx" * 2) + "ab"])
|
|
|
|
def test_okay_secret_key_fallbacks(self):
|
|
|
|
self.assertEqual(
|
|
|
|
len(settings.SECRET_KEY_FALLBACKS[0]),
|
|
|
|
base.SECRET_KEY_MIN_LENGTH,
|
|
|
|
)
|
|
|
|
self.assertGreater(
|
|
|
|
len(set(settings.SECRET_KEY_FALLBACKS[0])),
|
|
|
|
base.SECRET_KEY_MIN_UNIQUE_CHARACTERS,
|
|
|
|
)
|
|
|
|
self.assertEqual(base.check_secret_key_fallbacks(None), [])
|
|
|
|
|
|
|
|
def test_no_secret_key_fallbacks(self):
|
|
|
|
with self.settings(SECRET_KEY_FALLBACKS=None):
|
|
|
|
del settings.SECRET_KEY_FALLBACKS
|
|
|
|
self.assertEqual(
|
|
|
|
base.check_secret_key_fallbacks(None),
|
|
|
|
[
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS", id=base.W025.id),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
SECRET_KEY_FALLBACKS=[base.SECRET_KEY_INSECURE_PREFIX + get_random_secret_key()]
|
|
|
|
)
|
|
|
|
def test_insecure_secret_key_fallbacks(self):
|
|
|
|
self.assertEqual(
|
|
|
|
base.check_secret_key_fallbacks(None),
|
|
|
|
[
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS[0]", id=base.W025.id),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
@override_settings(SECRET_KEY_FALLBACKS=[("abcdefghijklmnopqrstuvwx" * 2) + "a"])
|
|
|
|
def test_low_length_secret_key_fallbacks(self):
|
|
|
|
self.assertEqual(
|
|
|
|
len(settings.SECRET_KEY_FALLBACKS[0]),
|
|
|
|
base.SECRET_KEY_MIN_LENGTH - 1,
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
base.check_secret_key_fallbacks(None),
|
|
|
|
[
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS[0]", id=base.W025.id),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
@override_settings(SECRET_KEY_FALLBACKS=["abcd" * 20])
|
|
|
|
def test_low_entropy_secret_key_fallbacks(self):
|
|
|
|
self.assertGreater(
|
|
|
|
len(settings.SECRET_KEY_FALLBACKS[0]),
|
|
|
|
base.SECRET_KEY_MIN_LENGTH,
|
|
|
|
)
|
|
|
|
self.assertLess(
|
|
|
|
len(set(settings.SECRET_KEY_FALLBACKS[0])),
|
|
|
|
base.SECRET_KEY_MIN_UNIQUE_CHARACTERS,
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
base.check_secret_key_fallbacks(None),
|
|
|
|
[
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS[0]", id=base.W025.id),
|
|
|
|
],
|
|
|
|
)
|
2022-02-04 03:24:19 +08:00
|
|
|
|
2021-12-14 11:47:03 +08:00
|
|
|
@override_settings(
|
|
|
|
SECRET_KEY_FALLBACKS=[
|
|
|
|
("abcdefghijklmnopqrstuvwx" * 2) + "ab",
|
|
|
|
"badkey",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_multiple_keys(self):
|
|
|
|
self.assertEqual(
|
|
|
|
base.check_secret_key_fallbacks(None),
|
|
|
|
[
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS[1]", id=base.W025.id),
|
|
|
|
],
|
|
|
|
)
|
2022-02-04 03:24:19 +08:00
|
|
|
|
2021-12-14 11:47:03 +08:00
|
|
|
@override_settings(
|
|
|
|
SECRET_KEY_FALLBACKS=[
|
|
|
|
("abcdefghijklmnopqrstuvwx" * 2) + "ab",
|
|
|
|
"badkey1",
|
|
|
|
"badkey2",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def test_multiple_bad_keys(self):
|
|
|
|
self.assertEqual(
|
|
|
|
base.check_secret_key_fallbacks(None),
|
|
|
|
[
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS[1]", id=base.W025.id),
|
|
|
|
Warning(base.W025.msg % "SECRET_KEY_FALLBACKS[2]", id=base.W025.id),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2015-04-18 05:38:20 +08:00
|
|
|
class CheckDebugTest(SimpleTestCase):
|
2014-09-13 02:50:36 +08:00
|
|
|
@override_settings(DEBUG=True)
|
|
|
|
def test_debug_true(self):
|
|
|
|
"""
|
|
|
|
Warn if DEBUG is True.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_debug(None), [base.W018])
|
2014-09-13 02:50:36 +08:00
|
|
|
|
|
|
|
@override_settings(DEBUG=False)
|
|
|
|
def test_debug_false(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_debug(None), [])
|
2015-06-17 04:08:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
class CheckAllowedHostsTest(SimpleTestCase):
|
|
|
|
@override_settings(ALLOWED_HOSTS=[])
|
|
|
|
def test_allowed_hosts_empty(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_allowed_hosts(None), [base.W020])
|
2015-06-17 04:08:03 +08:00
|
|
|
|
2017-12-29 04:07:29 +08:00
|
|
|
@override_settings(ALLOWED_HOSTS=[".example.com"])
|
2015-06-17 04:08:03 +08:00
|
|
|
def test_allowed_hosts_set(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_allowed_hosts(None), [])
|
2019-03-22 05:33:41 +08:00
|
|
|
|
|
|
|
|
|
|
|
class CheckReferrerPolicyTest(SimpleTestCase):
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_REFERRER_POLICY=None,
|
|
|
|
)
|
|
|
|
def test_no_referrer_policy(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_referrer_policy(None), [base.W022])
|
2019-03-22 05:33:41 +08:00
|
|
|
|
|
|
|
@override_settings(MIDDLEWARE=[], SECURE_REFERRER_POLICY=None)
|
|
|
|
def test_no_referrer_policy_no_middleware(self):
|
|
|
|
"""
|
|
|
|
Don't warn if SECURE_REFERRER_POLICY is None and SecurityMiddleware
|
|
|
|
isn't in MIDDLEWARE.
|
|
|
|
"""
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_referrer_policy(None), [])
|
2019-03-22 05:33:41 +08:00
|
|
|
|
|
|
|
@override_settings(MIDDLEWARE=["django.middleware.security.SecurityMiddleware"])
|
|
|
|
def test_with_referrer_policy(self):
|
|
|
|
tests = (
|
|
|
|
"strict-origin",
|
|
|
|
"strict-origin,origin",
|
|
|
|
"strict-origin, origin",
|
|
|
|
["strict-origin", "origin"],
|
|
|
|
("strict-origin", "origin"),
|
|
|
|
)
|
|
|
|
for value in tests:
|
|
|
|
with self.subTest(value=value), override_settings(
|
|
|
|
SECURE_REFERRER_POLICY=value
|
|
|
|
):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_referrer_policy(None), [])
|
2019-03-22 05:33:41 +08:00
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_REFERRER_POLICY="invalid-value",
|
|
|
|
)
|
|
|
|
def test_with_invalid_referrer_policy(self):
|
2020-03-22 03:14:02 +08:00
|
|
|
self.assertEqual(base.check_referrer_policy(None), [base.E023])
|
2021-01-12 16:44:36 +08:00
|
|
|
|
|
|
|
|
|
|
|
def failure_view_with_invalid_signature():
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class CSRFFailureViewTest(SimpleTestCase):
|
|
|
|
@override_settings(CSRF_FAILURE_VIEW="")
|
|
|
|
def test_failure_view_import_error(self):
|
|
|
|
self.assertEqual(
|
|
|
|
csrf.check_csrf_failure_view(None),
|
|
|
|
[
|
|
|
|
Error(
|
|
|
|
"The CSRF failure view '' could not be imported.",
|
2021-01-12 18:22:13 +08:00
|
|
|
id="security.E102",
|
2021-01-12 16:44:36 +08:00
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
@override_settings(
|
2021-01-12 18:22:13 +08:00
|
|
|
CSRF_FAILURE_VIEW=(
|
|
|
|
"check_framework.test_security.failure_view_with_invalid_signature"
|
|
|
|
),
|
2021-01-12 16:44:36 +08:00
|
|
|
)
|
|
|
|
def test_failure_view_invalid_signature(self):
|
|
|
|
msg = (
|
|
|
|
"The CSRF failure view "
|
|
|
|
"'check_framework.test_security.failure_view_with_invalid_signature' "
|
|
|
|
"does not take the correct number of arguments."
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
csrf.check_csrf_failure_view(None),
|
2021-01-12 18:22:13 +08:00
|
|
|
[Error(msg, id="security.E101")],
|
2021-01-12 16:44:36 +08:00
|
|
|
)
|
2020-08-27 00:09:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
class CheckCrossOriginOpenerPolicyTest(SimpleTestCase):
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_CROSS_ORIGIN_OPENER_POLICY=None,
|
|
|
|
)
|
|
|
|
def test_no_coop(self):
|
|
|
|
self.assertEqual(base.check_cross_origin_opener_policy(None), [])
|
|
|
|
|
|
|
|
@override_settings(MIDDLEWARE=["django.middleware.security.SecurityMiddleware"])
|
|
|
|
def test_with_coop(self):
|
|
|
|
tests = ["same-origin", "same-origin-allow-popups", "unsafe-none"]
|
|
|
|
for value in tests:
|
|
|
|
with self.subTest(value=value), override_settings(
|
|
|
|
SECURE_CROSS_ORIGIN_OPENER_POLICY=value,
|
|
|
|
):
|
|
|
|
self.assertEqual(base.check_cross_origin_opener_policy(None), [])
|
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
|
|
|
|
SECURE_CROSS_ORIGIN_OPENER_POLICY="invalid-value",
|
|
|
|
)
|
|
|
|
def test_with_invalid_coop(self):
|
|
|
|
self.assertEqual(base.check_cross_origin_opener_policy(None), [base.E024])
|