summaryrefslogtreecommitdiff
path: root/tests/csrf_tests
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2021-07-16 10:54:42 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-07-23 07:08:45 +0200
commita2e1f1e2954c8144f2acf83402ed1f55ea9692a4 (patch)
treefba55c6258a1a25f2d306ce2759f79d3899d1061 /tests/csrf_tests
parent311401d9a278339795a7ab3f1617c4da9077fdcc (diff)
downloaddjango-a2e1f1e2954c8144f2acf83402ed1f55ea9692a4.tar.gz
Fixed #32902 -- Fixed CsrfViewMiddleware.process_response()'s cookie reset logic.
Thanks Florian Apolloner and Shai Berger for reviews.
Diffstat (limited to 'tests/csrf_tests')
-rw-r--r--tests/csrf_tests/tests.py31
-rw-r--r--tests/csrf_tests/views.py11
2 files changed, 40 insertions, 2 deletions
diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py
index 691a5c1e2b..216625067c 100644
--- a/tests/csrf_tests/tests.py
+++ b/tests/csrf_tests/tests.py
@@ -14,8 +14,9 @@ from django.test import SimpleTestCase, override_settings
from django.views.decorators.csrf import csrf_exempt, requires_csrf_token
from .views import (
- ensure_csrf_cookie_view, non_token_view_using_request_processor,
- post_form_view, sandwiched_rotate_token_view, token_view,
+ ensure_csrf_cookie_view, ensured_and_protected_view,
+ non_token_view_using_request_processor, post_form_view, protected_view,
+ sandwiched_rotate_token_view, token_view,
)
# This is a test (unmasked) CSRF cookie / secret.
@@ -1065,6 +1066,32 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
resp = mw.process_view(req, token_view, (), {})
self.assertIsNone(resp)
+ def test_cookie_reset_only_once(self):
+ """
+ A CSRF cookie that needs to be reset is reset only once when the view
+ is decorated with both ensure_csrf_cookie and csrf_protect.
+ """
+ # Pass an unmasked cookie to trigger a cookie reset.
+ req = self._get_POST_request_with_token(cookie=TEST_SECRET)
+ resp = ensured_and_protected_view(req)
+ self.assertContains(resp, 'OK')
+ csrf_cookie = self._read_csrf_cookie(req, resp)
+ actual_secret = _unmask_cipher_token(csrf_cookie)
+ self.assertEqual(actual_secret, TEST_SECRET)
+ # set_cookie() was called only once and with the expected secret.
+ self.assertCookiesSet(req, resp, [TEST_SECRET])
+
+ def test_invalid_cookie_replaced_on_GET(self):
+ """
+ A CSRF cookie with the wrong format is replaced during a GET request.
+ """
+ req = self._get_request(cookie='badvalue')
+ resp = protected_view(req)
+ self.assertContains(resp, 'OK')
+ csrf_cookie = self._read_csrf_cookie(req, resp)
+ self.assertTrue(csrf_cookie, msg='No CSRF cookie was sent.')
+ self.assertEqual(len(csrf_cookie), CSRF_TOKEN_LENGTH)
+
def test_bare_secret_accepted_and_replaced(self):
"""
The csrf token is reset from a bare secret.
diff --git a/tests/csrf_tests/views.py b/tests/csrf_tests/views.py
index fce9ae06b1..2dafbf28e2 100644
--- a/tests/csrf_tests/views.py
+++ b/tests/csrf_tests/views.py
@@ -34,6 +34,17 @@ csrf_rotating_token = decorator_from_middleware(_CsrfCookieRotator)
@csrf_protect
+def protected_view(request):
+ return HttpResponse('OK')
+
+
+@csrf_protect
+@ensure_csrf_cookie
+def ensured_and_protected_view(request):
+ return TestingHttpResponse('OK')
+
+
+@csrf_protect
@csrf_rotating_token
@ensure_csrf_cookie
def sandwiched_rotate_token_view(request):