diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2021-07-16 10:54:42 -0400 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-07-23 07:08:45 +0200 |
commit | a2e1f1e2954c8144f2acf83402ed1f55ea9692a4 (patch) | |
tree | fba55c6258a1a25f2d306ce2759f79d3899d1061 /tests/csrf_tests | |
parent | 311401d9a278339795a7ab3f1617c4da9077fdcc (diff) | |
download | django-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.py | 31 | ||||
-rw-r--r-- | tests/csrf_tests/views.py | 11 |
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): |