Browse Source

Fixed #32311 -- Added system check for CSRF_FAILURE_VIEW setting.

Hasan Ramezani 4 years ago
parent
commit
64331419c8
3 changed files with 65 additions and 1 deletions
  1. 28 1
      django/core/checks/security/csrf.py
  2. 4 0
      docs/ref/checks.txt
  3. 33 0
      tests/check_framework/test_security.py

+ 28 - 1
django/core/checks/security/csrf.py

@@ -1,6 +1,8 @@
+import inspect
+
 from django.conf import settings
 
-from .. import Tags, Warning, register
+from .. import Error, Tags, Warning, register
 
 W003 = Warning(
     "You don't appear to be using Django's built-in "
@@ -38,3 +40,28 @@ def check_csrf_cookie_secure(app_configs, **kwargs):
         settings.CSRF_COOKIE_SECURE
     )
     return [] if passed_check else [W016]
+
+
+@register(Tags.security)
+def check_csrf_failure_view(app_configs, **kwargs):
+    from django.middleware.csrf import _get_failure_view
+
+    errors = []
+    try:
+        view = _get_failure_view()
+    except ImportError:
+        msg = (
+            "The CSRF failure view '%s' could not be imported." %
+            settings.CSRF_FAILURE_VIEW
+        )
+        errors.append(Error(msg, id='security.E025'))
+    else:
+        try:
+            inspect.signature(view).bind(None, reason=None)
+        except TypeError:
+            msg = (
+                "The CSRF failure view '%s' does not take the correct number of arguments." %
+                settings.CSRF_FAILURE_VIEW
+            )
+            errors.append(Error(msg, id='security.E024'))
+    return errors

+ 4 - 0
docs/ref/checks.txt

@@ -495,6 +495,10 @@ The following checks are run if you use the :option:`check --deploy` option:
   should consider enabling this header to protect user privacy.
 * **security.E023**: You have set the :setting:`SECURE_REFERRER_POLICY` setting
   to an invalid value.
+* **security.E024**: The CSRF failure view ``'path.to.view'`` does not take the
+  correct number of arguments.
+* **security.E025**: The CSRF failure view ``'path.to.view'`` could not be
+  imported.
 
 The following checks verify that your security-related settings are correctly
 configured:

+ 33 - 0
tests/check_framework/test_security.py

@@ -1,4 +1,5 @@
 from django.conf import settings
+from django.core.checks.messages import Error
 from django.core.checks.security import base, csrf, sessions
 from django.core.management.utils import get_random_secret_key
 from django.test import SimpleTestCase
@@ -471,3 +472,35 @@ class CheckReferrerPolicyTest(SimpleTestCase):
     )
     def test_with_invalid_referrer_policy(self):
         self.assertEqual(base.check_referrer_policy(None), [base.E023])
+
+
+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.",
+                    id='security.E025',
+                )
+            ],
+        )
+
+    @override_settings(
+        CSRF_FAILURE_VIEW=f'{__name__}.failure_view_with_invalid_signature',
+    )
+    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),
+            [Error(msg, id='security.E024')],
+        )