diff options
| author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2021-05-31 04:26:11 -0700 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-06-01 09:02:27 +0200 |
| commit | cd19db10df6225e01b77685397a88c9cdf216dd1 (patch) | |
| tree | f00918fc29389fa81001c0fa3650d398dd1afcbe | |
| parent | 623cec0879e09e8ad804c213157e51e764f5d826 (diff) | |
Fixed #32796 -- Changed CsrfViewMiddleware to fail earlier on badly formatted cookie tokens.
| -rw-r--r-- | django/middleware/csrf.py | 23 | ||||
| -rw-r--r-- | tests/csrf_tests/tests.py | 4 |
2 files changed, 17 insertions, 10 deletions
diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index 3febfd9486..5d77b19c7c 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -217,14 +217,12 @@ class CsrfViewMiddleware(MiddlewareMixin): except KeyError: return None - try: - csrf_token = _sanitize_token(cookie_token) - except InvalidTokenFormat: - csrf_token = _get_new_csrf_token() + # This can raise InvalidTokenFormat. + csrf_token = _sanitize_token(cookie_token) if csrf_token != cookie_token: - # Cookie token needed to be replaced; - # the cookie needs to be reset. + # Then the cookie token had length CSRF_SECRET_LENGTH, so flag + # to replace it with the masked version. request.csrf_cookie_needs_reset = True return csrf_token @@ -318,7 +316,12 @@ class CsrfViewMiddleware(MiddlewareMixin): raise RejectRequest(REASON_BAD_REFERER % referer.geturl()) def process_request(self, request): - csrf_token = self._get_token(request) + try: + csrf_token = self._get_token(request) + except InvalidTokenFormat: + csrf_token = _get_new_csrf_token() + request.csrf_cookie_needs_reset = True + if csrf_token is not None: # Use same token next time. request.META['CSRF_COOKIE'] = csrf_token @@ -374,7 +377,11 @@ class CsrfViewMiddleware(MiddlewareMixin): # Access csrf_token via self._get_token() as rotate_token() may have # been called by an authentication middleware during the # process_request() phase. - csrf_token = self._get_token(request) + try: + csrf_token = self._get_token(request) + except InvalidTokenFormat as exc: + return self._reject(request, f'CSRF cookie {exc.reason}.') + if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index f68828065f..7cf69fd6c5 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -863,14 +863,14 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase): If the CSRF cookie has invalid characters in a POST request, the middleware rejects the incoming request. """ - self._check_bad_or_missing_cookie(64 * '*', REASON_CSRF_TOKEN_MISSING) + self._check_bad_or_missing_cookie(64 * '*', 'CSRF cookie has invalid characters.') def test_bad_csrf_cookie_length(self): """ If the CSRF cookie has an incorrect length in a POST request, the middleware rejects the incoming request. """ - self._check_bad_or_missing_cookie(16 * 'a', REASON_CSRF_TOKEN_MISSING) + self._check_bad_or_missing_cookie(16 * 'a', 'CSRF cookie has incorrect length.') def test_process_view_token_too_long(self): """ |
