summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2021-05-31 04:26:11 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-06-01 09:02:27 +0200
commitcd19db10df6225e01b77685397a88c9cdf216dd1 (patch)
treef00918fc29389fa81001c0fa3650d398dd1afcbe
parent623cec0879e09e8ad804c213157e51e764f5d826 (diff)
Fixed #32796 -- Changed CsrfViewMiddleware to fail earlier on badly formatted cookie tokens.
-rw-r--r--django/middleware/csrf.py23
-rw-r--r--tests/csrf_tests/tests.py4
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):
"""