summaryrefslogtreecommitdiff
path: root/tests/csrf_tests
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/csrf_tests
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
downloaddjango-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/csrf_tests')
-rw-r--r--tests/csrf_tests/csrf_token_error_handler_urls.py2
-rw-r--r--tests/csrf_tests/test_context_processor.py7
-rw-r--r--tests/csrf_tests/tests.py595
-rw-r--r--tests/csrf_tests/views.py20
4 files changed, 354 insertions, 270 deletions
diff --git a/tests/csrf_tests/csrf_token_error_handler_urls.py b/tests/csrf_tests/csrf_token_error_handler_urls.py
index 3c02f613ec..f7007d740b 100644
--- a/tests/csrf_tests/csrf_token_error_handler_urls.py
+++ b/tests/csrf_tests/csrf_token_error_handler_urls.py
@@ -1,3 +1,3 @@
urlpatterns = []
-handler404 = 'csrf_tests.views.csrf_token_error_handler'
+handler404 = "csrf_tests.views.csrf_token_error_handler"
diff --git a/tests/csrf_tests/test_context_processor.py b/tests/csrf_tests/test_context_processor.py
index 26a2b7aedb..903237d68f 100644
--- a/tests/csrf_tests/test_context_processor.py
+++ b/tests/csrf_tests/test_context_processor.py
@@ -6,10 +6,9 @@ from .tests import CsrfFunctionTestMixin
class TestContextProcessor(CsrfFunctionTestMixin, SimpleTestCase):
-
def test_force_token_to_string(self):
request = HttpRequest()
- test_secret = 32 * 'a'
- request.META['CSRF_COOKIE'] = test_secret
- token = csrf(request).get('csrf_token')
+ test_secret = 32 * "a"
+ request.META["CSRF_COOKIE"] = test_secret
+ token = csrf(request).get("csrf_token")
self.assertMaskedSecretCorrect(token, test_secret)
diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py
index 71e75854db..6c8f5e1f04 100644
--- a/tests/csrf_tests/tests.py
+++ b/tests/csrf_tests/tests.py
@@ -5,11 +5,22 @@ from django.contrib.sessions.backends.cache import SessionStore
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpRequest, HttpResponse, UnreadablePostError
from django.middleware.csrf import (
- CSRF_ALLOWED_CHARS, CSRF_SECRET_LENGTH, CSRF_SESSION_KEY,
- CSRF_TOKEN_LENGTH, REASON_BAD_ORIGIN, REASON_CSRF_TOKEN_MISSING,
- REASON_NO_CSRF_COOKIE, CsrfViewMiddleware, InvalidTokenFormat,
- RejectRequest, _check_token_format, _does_token_match, _mask_cipher_secret,
- _unmask_cipher_token, get_token, rotate_token,
+ CSRF_ALLOWED_CHARS,
+ CSRF_SECRET_LENGTH,
+ CSRF_SESSION_KEY,
+ CSRF_TOKEN_LENGTH,
+ REASON_BAD_ORIGIN,
+ REASON_CSRF_TOKEN_MISSING,
+ REASON_NO_CSRF_COOKIE,
+ CsrfViewMiddleware,
+ InvalidTokenFormat,
+ RejectRequest,
+ _check_token_format,
+ _does_token_match,
+ _mask_cipher_secret,
+ _unmask_cipher_token,
+ get_token,
+ rotate_token,
)
from django.test import SimpleTestCase, override_settings
from django.test.utils import ignore_warnings
@@ -17,16 +28,20 @@ from django.utils.deprecation import RemovedInDjango50Warning
from django.views.decorators.csrf import csrf_exempt, requires_csrf_token
from .views import (
- 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,
+ 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.
-TEST_SECRET = 'lcccccccX2kcccccccY2jcccccccssIC'
+TEST_SECRET = "lcccccccX2kcccccccY2jcccccccssIC"
# Two masked versions of TEST_SECRET for testing purposes.
-MASKED_TEST_SECRET1 = '1bcdefghij2bcdefghij3bcdefghij4bcdefghij5bcdefghij6bcdefghijABCD'
-MASKED_TEST_SECRET2 = '2JgchWvM1tpxT2lfz9aydoXW9yT1DN3NdLiejYxOOlzzV4nhBbYqmqZYbAV3V5Bf'
+MASKED_TEST_SECRET1 = "1bcdefghij2bcdefghij3bcdefghij4bcdefghij5bcdefghij6bcdefghijABCD"
+MASKED_TEST_SECRET2 = "2JgchWvM1tpxT2lfz9aydoXW9yT1DN3NdLiejYxOOlzzV4nhBbYqmqZYbAV3V5Bf"
class CsrfFunctionTestMixin:
@@ -38,27 +53,26 @@ class CsrfFunctionTestMixin:
self.assertEqual(len(secret), CSRF_SECRET_LENGTH)
self.assertTrue(
set(masked_secret).issubset(set(CSRF_ALLOWED_CHARS)),
- msg=f'invalid characters in {masked_secret!r}',
+ msg=f"invalid characters in {masked_secret!r}",
)
actual = _unmask_cipher_token(masked_secret)
self.assertEqual(actual, secret)
class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
-
def test_unmask_cipher_token(self):
cases = [
(TEST_SECRET, MASKED_TEST_SECRET1),
(TEST_SECRET, MASKED_TEST_SECRET2),
(
- 32 * 'a',
- 'vFioG3XOLyGyGsPRFyB9iYUs341ufzIEvFioG3XOLyGyGsPRFyB9iYUs341ufzIE',
+ 32 * "a",
+ "vFioG3XOLyGyGsPRFyB9iYUs341ufzIEvFioG3XOLyGyGsPRFyB9iYUs341ufzIE",
),
- (32 * 'a', 64 * 'a'),
- (32 * 'a', 64 * 'b'),
- (32 * 'b', 32 * 'a' + 32 * 'b'),
- (32 * 'b', 32 * 'b' + 32 * 'c'),
- (32 * 'c', 32 * 'a' + 32 * 'c'),
+ (32 * "a", 64 * "a"),
+ (32 * "a", 64 * "b"),
+ (32 * "b", 32 * "a" + 32 * "b"),
+ (32 * "b", 32 * "b" + 32 * "c"),
+ (32 * "c", 32 * "a" + 32 * "c"),
]
for secret, masked_secret in cases:
with self.subTest(masked_secret=masked_secret):
@@ -67,9 +81,9 @@ class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
def test_mask_cipher_secret(self):
cases = [
- 32 * 'a',
+ 32 * "a",
TEST_SECRET,
- 'da4SrUiHJYoJ0HYQ0vcgisoIuFOxx4ER',
+ "da4SrUiHJYoJ0HYQ0vcgisoIuFOxx4ER",
]
for secret in cases:
with self.subTest(secret=secret):
@@ -78,33 +92,33 @@ class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
def test_get_token_csrf_cookie_set(self):
request = HttpRequest()
- request.META['CSRF_COOKIE'] = TEST_SECRET
- self.assertNotIn('CSRF_COOKIE_NEEDS_UPDATE', request.META)
+ request.META["CSRF_COOKIE"] = TEST_SECRET
+ self.assertNotIn("CSRF_COOKIE_NEEDS_UPDATE", request.META)
token = get_token(request)
self.assertMaskedSecretCorrect(token, TEST_SECRET)
# The existing cookie is preserved.
- self.assertEqual(request.META['CSRF_COOKIE'], TEST_SECRET)
- self.assertIs(request.META['CSRF_COOKIE_NEEDS_UPDATE'], True)
+ self.assertEqual(request.META["CSRF_COOKIE"], TEST_SECRET)
+ self.assertIs(request.META["CSRF_COOKIE_NEEDS_UPDATE"], True)
def test_get_token_csrf_cookie_not_set(self):
request = HttpRequest()
- self.assertNotIn('CSRF_COOKIE', request.META)
- self.assertNotIn('CSRF_COOKIE_NEEDS_UPDATE', request.META)
+ self.assertNotIn("CSRF_COOKIE", request.META)
+ self.assertNotIn("CSRF_COOKIE_NEEDS_UPDATE", request.META)
token = get_token(request)
- cookie = request.META['CSRF_COOKIE']
+ cookie = request.META["CSRF_COOKIE"]
self.assertMaskedSecretCorrect(token, cookie)
- self.assertIs(request.META['CSRF_COOKIE_NEEDS_UPDATE'], True)
+ self.assertIs(request.META["CSRF_COOKIE_NEEDS_UPDATE"], True)
def test_rotate_token(self):
request = HttpRequest()
- request.META['CSRF_COOKIE'] = TEST_SECRET
- self.assertNotIn('CSRF_COOKIE_NEEDS_UPDATE', request.META)
+ request.META["CSRF_COOKIE"] = TEST_SECRET
+ self.assertNotIn("CSRF_COOKIE_NEEDS_UPDATE", request.META)
rotate_token(request)
# The underlying secret was changed.
- cookie = request.META['CSRF_COOKIE']
+ cookie = request.META["CSRF_COOKIE"]
self.assertEqual(len(cookie), CSRF_SECRET_LENGTH)
self.assertNotEqual(cookie, TEST_SECRET)
- self.assertIs(request.META['CSRF_COOKIE_NEEDS_UPDATE'], True)
+ self.assertIs(request.META["CSRF_COOKIE_NEEDS_UPDATE"], True)
def test_check_token_format_valid(self):
cases = [
@@ -112,7 +126,7 @@ class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
TEST_SECRET,
# A token of length CSRF_TOKEN_LENGTH.
MASKED_TEST_SECRET1,
- 64 * 'a',
+ 64 * "a",
]
for token in cases:
with self.subTest(token=token):
@@ -121,8 +135,8 @@ class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
def test_check_token_format_invalid(self):
cases = [
- (64 * '*', 'has invalid characters'),
- (16 * 'a', 'has incorrect length'),
+ (64 * "*", "has invalid characters"),
+ (16 * "a", "has incorrect length"),
]
for token, expected_message in cases:
with self.subTest(token=token):
@@ -134,13 +148,13 @@ class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
# Masked tokens match.
((MASKED_TEST_SECRET1, TEST_SECRET), True),
((MASKED_TEST_SECRET2, TEST_SECRET), True),
- ((64 * 'a', _unmask_cipher_token(64 * 'a')), True),
+ ((64 * "a", _unmask_cipher_token(64 * "a")), True),
# Unmasked tokens match.
((TEST_SECRET, TEST_SECRET), True),
- ((32 * 'a', 32 * 'a'), True),
+ ((32 * "a", 32 * "a"), True),
# Incorrect tokens don't match.
- ((32 * 'a', TEST_SECRET), False),
- ((64 * 'a', TEST_SECRET), False),
+ ((32 * "a", TEST_SECRET), False),
+ ((64 * "a", TEST_SECRET), False),
]
for (token, secret), expected in cases:
with self.subTest(token=token, secret=secret):
@@ -149,7 +163,7 @@ class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
def test_does_token_match_wrong_token_length(self):
with self.assertRaises(AssertionError):
- _does_token_match(16 * 'a', TEST_SECRET)
+ _does_token_match(16 * "a", TEST_SECRET)
class TestingSessionStore(SessionStore):
@@ -157,6 +171,7 @@ class TestingSessionStore(SessionStore):
A version of SessionStore that stores what cookie values are passed to
set_cookie() when CSRF_USE_SESSIONS=True.
"""
+
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# This is a list of the cookie values passed to set_cookie() over
@@ -173,18 +188,20 @@ class TestingHttpRequest(HttpRequest):
A version of HttpRequest that lets one track and change some things more
easily.
"""
+
def __init__(self):
super().__init__()
self.session = TestingSessionStore()
def is_secure(self):
- return getattr(self, '_is_secure_override', False)
+ return getattr(self, "_is_secure_override", False)
class PostErrorRequest(TestingHttpRequest):
"""
TestingHttpRequest that can raise errors when accessing POST data.
"""
+
post_error = None
def _get_post(self):
@@ -207,24 +224,24 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
_csrf_id_token = MASKED_TEST_SECRET2
def _set_csrf_cookie(self, req, cookie):
- raise NotImplementedError('This method must be implemented by a subclass.')
+ raise NotImplementedError("This method must be implemented by a subclass.")
def _read_csrf_cookie(self, req, resp):
"""
Return the CSRF cookie as a string, or False if no cookie is present.
"""
- raise NotImplementedError('This method must be implemented by a subclass.')
+ raise NotImplementedError("This method must be implemented by a subclass.")
def _get_cookies_set(self, req, resp):
"""
Return a list of the cookie values passed to set_cookie() over the
course of the request-response.
"""
- raise NotImplementedError('This method must be implemented by a subclass.')
+ raise NotImplementedError("This method must be implemented by a subclass.")
def _get_request(self, method=None, cookie=None, request_class=None):
if method is None:
- method = 'GET'
+ method = "GET"
if request_class is None:
request_class = TestingHttpRequest
req = request_class()
@@ -234,8 +251,13 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
return req
def _get_csrf_cookie_request(
- self, method=None, cookie=None, post_token=None, meta_token=None,
- token_header=None, request_class=None,
+ self,
+ method=None,
+ cookie=None,
+ post_token=None,
+ meta_token=None,
+ token_header=None,
+ request_class=None,
):
"""
The method argument defaults to "GET". The cookie argument defaults to
@@ -248,25 +270,32 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
if cookie is None:
cookie = self._csrf_id_cookie
if token_header is None:
- token_header = 'HTTP_X_CSRFTOKEN'
+ token_header = "HTTP_X_CSRFTOKEN"
req = self._get_request(
method=method,
cookie=cookie,
request_class=request_class,
)
if post_token is not None:
- req.POST['csrfmiddlewaretoken'] = post_token
+ req.POST["csrfmiddlewaretoken"] = post_token
if meta_token is not None:
req.META[token_header] = meta_token
return req
def _get_POST_csrf_cookie_request(
- self, cookie=None, post_token=None, meta_token=None, token_header=None,
+ self,
+ cookie=None,
+ post_token=None,
+ meta_token=None,
+ token_header=None,
request_class=None,
):
return self._get_csrf_cookie_request(
- method='POST', cookie=cookie, post_token=post_token,
- meta_token=meta_token, token_header=token_header,
+ method="POST",
+ cookie=cookie,
+ post_token=post_token,
+ meta_token=meta_token,
+ token_header=token_header,
request_class=request_class,
)
@@ -285,7 +314,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
text = str(response.content, response.charset)
match = re.search('name="csrfmiddlewaretoken" value="(.*?)"', text)
self.assertTrue(
- match, f'Could not find a csrfmiddlewaretoken value in: {text}',
+ match,
+ f"Could not find a csrfmiddlewaretoken value in: {text}",
)
csrf_token = match[1]
self.assertMaskedSecretCorrect(csrf_token, csrf_secret)
@@ -313,13 +343,13 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
def _check_bad_or_missing_cookie(self, cookie, expected):
"""Passing None for cookie includes no cookie."""
- req = self._get_request(method='POST', cookie=cookie)
+ req = self._get_request(method="POST", cookie=cookie)
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
self.assertEqual(403, resp.status_code)
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % expected)
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected)
def test_no_csrf_cookie(self):
"""
@@ -329,7 +359,11 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
self._check_bad_or_missing_cookie(None, REASON_NO_CSRF_COOKIE)
def _check_bad_or_missing_token(
- self, expected, post_token=None, meta_token=None, token_header=None,
+ self,
+ expected,
+ post_token=None,
+ meta_token=None,
+ token_header=None,
):
req = self._get_POST_csrf_cookie_request(
post_token=post_token,
@@ -338,10 +372,10 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
)
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
self.assertEqual(403, resp.status_code)
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % expected)
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected)
def test_csrf_cookie_bad_or_missing_token(self):
"""
@@ -350,22 +384,22 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
cases = [
(None, None, REASON_CSRF_TOKEN_MISSING),
- (16 * 'a', None, 'CSRF token from POST has incorrect length.'),
- (64 * '*', None, 'CSRF token from POST has invalid characters.'),
- (64 * 'a', None, 'CSRF token from POST incorrect.'),
+ (16 * "a", None, "CSRF token from POST has incorrect length."),
+ (64 * "*", None, "CSRF token from POST has invalid characters."),
+ (64 * "a", None, "CSRF token from POST incorrect."),
(
None,
- 16 * 'a',
+ 16 * "a",
"CSRF token from the 'X-Csrftoken' HTTP header has incorrect length.",
),
(
None,
- 64 * '*',
+ 64 * "*",
"CSRF token from the 'X-Csrftoken' HTTP header has invalid characters.",
),
(
None,
- 64 * 'a',
+ 64 * "a",
"CSRF token from the 'X-Csrftoken' HTTP header incorrect.",
),
]
@@ -377,7 +411,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
meta_token=meta_token,
)
- @override_settings(CSRF_HEADER_NAME='HTTP_X_CSRFTOKEN_CUSTOMIZED')
+ @override_settings(CSRF_HEADER_NAME="HTTP_X_CSRFTOKEN_CUSTOMIZED")
def test_csrf_cookie_bad_token_custom_header(self):
"""
If a CSRF cookie is present and an invalid token is passed via a
@@ -389,8 +423,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
)
self._check_bad_or_missing_token(
expected,
- meta_token=16 * 'a',
- token_header='HTTP_X_CSRFTOKEN_CUSTOMIZED',
+ meta_token=16 * "a",
+ token_header="HTTP_X_CSRFTOKEN_CUSTOMIZED",
)
def test_process_request_csrf_cookie_and_token(self):
@@ -424,14 +458,14 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- @override_settings(CSRF_HEADER_NAME='HTTP_X_CSRFTOKEN_CUSTOMIZED')
+ @override_settings(CSRF_HEADER_NAME="HTTP_X_CSRFTOKEN_CUSTOMIZED")
def test_csrf_token_in_header_with_customized_name(self):
"""
settings.CSRF_HEADER_NAME can be used to customize the CSRF header name
"""
req = self._get_POST_csrf_cookie_request(
meta_token=self._csrf_id_token,
- token_header='HTTP_X_CSRFTOKEN_CUSTOMIZED',
+ token_header="HTTP_X_CSRFTOKEN_CUSTOMIZED",
)
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
@@ -442,30 +476,38 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
HTTP PUT and DELETE methods have protection
"""
- req = self._get_request(method='PUT')
+ req = self._get_request(method="PUT")
mw = CsrfViewMiddleware(post_form_view)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
self.assertEqual(403, resp.status_code)
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % REASON_NO_CSRF_COOKIE)
+ self.assertEqual(
+ cm.records[0].getMessage(), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE
+ )
- req = self._get_request(method='DELETE')
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ req = self._get_request(method="DELETE")
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
self.assertEqual(403, resp.status_code)
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % REASON_NO_CSRF_COOKIE)
+ self.assertEqual(
+ cm.records[0].getMessage(), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE
+ )
def test_put_and_delete_allowed(self):
"""
HTTP PUT and DELETE can get through with X-CSRFToken and a cookie.
"""
- req = self._get_csrf_cookie_request(method='PUT', meta_token=self._csrf_id_token)
+ req = self._get_csrf_cookie_request(
+ method="PUT", meta_token=self._csrf_id_token
+ )
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- req = self._get_csrf_cookie_request(method='DELETE', meta_token=self._csrf_id_token)
+ req = self._get_csrf_cookie_request(
+ method="DELETE", meta_token=self._csrf_id_token
+ )
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
@@ -478,7 +520,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
resp = sandwiched_rotate_token_view(req)
- self.assertContains(resp, 'OK')
+ self.assertContains(resp, "OK")
actual_secret = self._read_csrf_cookie(req, resp)
# set_cookie() was called a second time with a different secret.
cookies_set = self._get_cookies_set(req, resp)
@@ -504,7 +546,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
A new token is sent if the csrf_cookie is the empty string.
"""
- req = self._get_request(cookie='')
+ req = self._get_request(cookie="")
mw = CsrfViewMiddleware(token_view)
mw.process_view(req, token_view, (), {})
resp = token_view(req)
@@ -569,26 +611,27 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
resp = mw(req)
csrf_cookie = self._read_csrf_cookie(req, resp)
self.assertEqual(
- csrf_cookie, TEST_SECRET,
- 'CSRF cookie was changed on an accepted request',
+ csrf_cookie,
+ TEST_SECRET,
+ "CSRF cookie was changed on an accepted request",
)
- @override_settings(DEBUG=True, ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(DEBUG=True, ALLOWED_HOSTS=["www.example.com"])
def test_https_bad_referer(self):
"""
A POST HTTPS request with a bad referer is rejected
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage'
- req.META['SERVER_PORT'] = '443'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_REFERER"] = "https://www.evil.org/somepage"
+ req.META["SERVER_PORT"] = "443"
mw = CsrfViewMiddleware(post_form_view)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(
response,
- 'Referer checking failed - https://www.evil.org/somepage does not '
- 'match any trusted origins.',
+ "Referer checking failed - https://www.evil.org/somepage does not "
+ "match any trusted origins.",
status_code=403,
)
@@ -606,7 +649,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(
response,
- 'Referer checking failed - no Referer.',
+ "Referer checking failed - no Referer.",
status_code=403,
)
@@ -615,15 +658,15 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
CsrfViewMiddleware generates a 403 response if it receives an HTTPS
request with a bad host.
"""
- req = self._get_request(method='POST')
+ req = self._get_request(method="POST")
req._is_secure_override = True
- req.META['HTTP_HOST'] = '@malformed'
- req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage'
- req.META['SERVER_PORT'] = '443'
+ req.META["HTTP_HOST"] = "@malformed"
+ req.META["HTTP_REFERER"] = "https://www.evil.org/somepage"
+ req.META["SERVER_PORT"] = "443"
mw = CsrfViewMiddleware(token_view)
expected = (
- 'Referer checking failed - https://www.evil.org/somepage does not '
- 'match any trusted origins.'
+ "Referer checking failed - https://www.evil.org/somepage does not "
+ "match any trusted origins."
)
with self.assertRaisesMessage(RejectRequest, expected):
mw._check_referer(req)
@@ -631,10 +674,10 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
self.assertEqual(response.status_code, 403)
def test_origin_malformed_host(self):
- req = self._get_request(method='POST')
+ req = self._get_request(method="POST")
req._is_secure_override = True
- req.META['HTTP_HOST'] = '@malformed'
- req.META['HTTP_ORIGIN'] = 'https://www.evil.org'
+ req.META["HTTP_HOST"] = "@malformed"
+ req.META["HTTP_ORIGIN"] = "https://www.evil.org"
mw = CsrfViewMiddleware(token_view)
self._check_referer_rejects(mw, req)
response = mw.process_view(req, token_view, (), {})
@@ -645,65 +688,65 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
A POST HTTPS request with a bad referer is rejected.
"""
- malformed_referer_msg = 'Referer checking failed - Referer is malformed.'
+ malformed_referer_msg = "Referer checking failed - Referer is malformed."
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_REFERER'] = 'http://http://www.example.com/'
+ req.META["HTTP_REFERER"] = "http://http://www.example.com/"
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(
response,
- 'Referer checking failed - Referer is insecure while host is secure.',
+ "Referer checking failed - Referer is insecure while host is secure.",
status_code=403,
)
# Empty
- req.META['HTTP_REFERER'] = ''
+ req.META["HTTP_REFERER"] = ""
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(response, malformed_referer_msg, status_code=403)
# Non-ASCII
- req.META['HTTP_REFERER'] = 'ØBöIß'
+ req.META["HTTP_REFERER"] = "ØBöIß"
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(response, malformed_referer_msg, status_code=403)
# missing scheme
# >>> urlparse('//example.com/')
# ParseResult(scheme='', netloc='example.com', path='/', params='', query='', fragment='')
- req.META['HTTP_REFERER'] = '//example.com/'
+ req.META["HTTP_REFERER"] = "//example.com/"
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(response, malformed_referer_msg, status_code=403)
# missing netloc
# >>> urlparse('https://')
# ParseResult(scheme='https', netloc='', path='', params='', query='', fragment='')
- req.META['HTTP_REFERER'] = 'https://'
+ req.META["HTTP_REFERER"] = "https://"
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(response, malformed_referer_msg, status_code=403)
# Invalid URL
# >>> urlparse('https://[')
# ValueError: Invalid IPv6 URL
- req.META['HTTP_REFERER'] = 'https://['
+ req.META["HTTP_REFERER"] = "https://["
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(response, malformed_referer_msg, status_code=403)
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_https_good_referer(self):
"""
A POST HTTPS request with a good referer is accepted.
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_REFERER'] = 'https://www.example.com/somepage'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_REFERER"] = "https://www.example.com/somepage"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_https_good_referer_2(self):
"""
A POST HTTPS request with a good referer is accepted where the referer
@@ -712,8 +755,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
# See ticket #15617
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_REFERER'] = 'https://www.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_REFERER"] = "https://www.example.com"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
@@ -722,19 +765,21 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
def _test_https_good_referer_behind_proxy(self):
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META.update({
- 'HTTP_HOST': '10.0.0.2',
- 'HTTP_REFERER': 'https://www.example.com/somepage',
- 'SERVER_PORT': '8080',
- 'HTTP_X_FORWARDED_HOST': 'www.example.com',
- 'HTTP_X_FORWARDED_PORT': '443',
- })
+ req.META.update(
+ {
+ "HTTP_HOST": "10.0.0.2",
+ "HTTP_REFERER": "https://www.example.com/somepage",
+ "SERVER_PORT": "8080",
+ "HTTP_X_FORWARDED_HOST": "www.example.com",
+ "HTTP_X_FORWARDED_PORT": "443",
+ }
+ )
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- @override_settings(CSRF_TRUSTED_ORIGINS=['https://dashboard.example.com'])
+ @override_settings(CSRF_TRUSTED_ORIGINS=["https://dashboard.example.com"])
def test_https_good_referer_malformed_host(self):
"""
A POST HTTPS request is accepted if it receives a good referer with
@@ -742,14 +787,17 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = '@malformed'
- req.META['HTTP_REFERER'] = 'https://dashboard.example.com/somepage'
+ req.META["HTTP_HOST"] = "@malformed"
+ req.META["HTTP_REFERER"] = "https://dashboard.example.com/somepage"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_TRUSTED_ORIGINS=['https://dashboard.example.com'])
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"],
+ CSRF_TRUSTED_ORIGINS=["https://dashboard.example.com"],
+ )
def test_https_csrf_trusted_origin_allowed(self):
"""
A POST HTTPS request with a referer added to the CSRF_TRUSTED_ORIGINS
@@ -757,14 +805,17 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_REFERER'] = 'https://dashboard.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_REFERER"] = "https://dashboard.example.com"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_TRUSTED_ORIGINS=['https://*.example.com'])
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"],
+ CSRF_TRUSTED_ORIGINS=["https://*.example.com"],
+ )
def test_https_csrf_wildcard_trusted_origin_allowed(self):
"""
A POST HTTPS request with a referer that matches a CSRF_TRUSTED_ORIGINS
@@ -772,8 +823,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_REFERER'] = 'https://dashboard.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_REFERER"] = "https://dashboard.example.com"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
response = mw.process_view(req, post_form_view, (), {})
@@ -782,8 +833,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
def _test_https_good_referer_matches_cookie_domain(self):
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_REFERER'] = 'https://foo.example.com/'
- req.META['SERVER_PORT'] = '443'
+ req.META["HTTP_REFERER"] = "https://foo.example.com/"
+ req.META["SERVER_PORT"] = "443"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
response = mw.process_view(req, post_form_view, (), {})
@@ -792,9 +843,9 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
def _test_https_good_referer_matches_cookie_domain_with_different_port(self):
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_REFERER'] = 'https://foo.example.com:4443/'
- req.META['SERVER_PORT'] = '4443'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_REFERER"] = "https://foo.example.com:4443/"
+ req.META["SERVER_PORT"] = "4443"
mw = CsrfViewMiddleware(post_form_view)
mw.process_request(req)
response = mw.process_view(req, post_form_view, (), {})
@@ -804,7 +855,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
ensure_csrf_cookie() doesn't log warnings (#19436).
"""
- with self.assertNoLogs('django.request', 'WARNING'):
+ with self.assertNoLogs("django.request", "WARNING"):
req = self._get_request()
ensure_csrf_cookie_view(req)
@@ -820,14 +871,14 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
self.assertIsNone(resp)
req = self._get_POST_request_with_token(request_class=PostErrorRequest)
- req.post_error = UnreadablePostError('Error reading input data.')
+ req.post_error = UnreadablePostError("Error reading input data.")
mw.process_request(req)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
self.assertEqual(resp.status_code, 403)
self.assertEqual(
cm.records[0].getMessage(),
- 'Forbidden (%s): ' % REASON_CSRF_TOKEN_MISSING,
+ "Forbidden (%s): " % REASON_CSRF_TOKEN_MISSING,
)
def test_reading_post_data_raises_os_error(self):
@@ -837,64 +888,64 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
mw = CsrfViewMiddleware(post_form_view)
req = self._get_POST_request_with_token(request_class=PostErrorRequest)
- req.post_error = OSError('Deleted directories/Missing permissions.')
+ req.post_error = OSError("Deleted directories/Missing permissions.")
mw.process_request(req)
with self.assertRaises(OSError):
mw.process_view(req, post_form_view, (), {})
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_bad_origin_bad_domain(self):
"""A request with a bad origin is rejected."""
req = self._get_POST_request_with_token()
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'https://www.evil.org'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "https://www.evil.org"
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
self.assertIs(mw._origin_verified(req), False)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
self.assertEqual(response.status_code, 403)
- msg = REASON_BAD_ORIGIN % req.META['HTTP_ORIGIN']
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % msg)
+ msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_bad_origin_null_origin(self):
"""A request with a null origin is rejected."""
req = self._get_POST_request_with_token()
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'null'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "null"
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
self.assertIs(mw._origin_verified(req), False)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
self.assertEqual(response.status_code, 403)
- msg = REASON_BAD_ORIGIN % req.META['HTTP_ORIGIN']
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % msg)
+ msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_bad_origin_bad_protocol(self):
"""A request with an origin with wrong protocol is rejected."""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'http://example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "http://example.com"
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
self.assertIs(mw._origin_verified(req), False)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
self.assertEqual(response.status_code, 403)
- msg = REASON_BAD_ORIGIN % req.META['HTTP_ORIGIN']
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % msg)
+ msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
@override_settings(
- ALLOWED_HOSTS=['www.example.com'],
+ ALLOWED_HOSTS=["www.example.com"],
CSRF_TRUSTED_ORIGINS=[
- 'http://no-match.com',
- 'https://*.example.com',
- 'http://*.no-match.com',
- 'http://*.no-match-2.com',
+ "http://no-match.com",
+ "https://*.example.com",
+ "http://*.no-match.com",
+ "http://*.no-match-2.com",
],
)
def test_bad_origin_csrf_trusted_origin_bad_protocol(self):
@@ -904,64 +955,70 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'http://foo.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "http://foo.example.com"
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
self.assertIs(mw._origin_verified(req), False)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
self.assertEqual(response.status_code, 403)
- msg = REASON_BAD_ORIGIN % req.META['HTTP_ORIGIN']
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % msg)
- self.assertEqual(mw.allowed_origins_exact, {'http://no-match.com'})
- self.assertEqual(mw.allowed_origin_subdomains, {
- 'https': ['.example.com'],
- 'http': ['.no-match.com', '.no-match-2.com'],
- })
-
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
+ self.assertEqual(mw.allowed_origins_exact, {"http://no-match.com"})
+ self.assertEqual(
+ mw.allowed_origin_subdomains,
+ {
+ "https": [".example.com"],
+ "http": [".no-match.com", ".no-match-2.com"],
+ },
+ )
+
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_bad_origin_cannot_be_parsed(self):
"""
A POST request with an origin that can't be parsed by urlparse() is
rejected.
"""
req = self._get_POST_request_with_token()
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'https://['
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "https://["
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
self.assertIs(mw._origin_verified(req), False)
- with self.assertLogs('django.security.csrf', 'WARNING') as cm:
+ with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
self.assertEqual(response.status_code, 403)
- msg = REASON_BAD_ORIGIN % req.META['HTTP_ORIGIN']
- self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % msg)
+ msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
+ self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_good_origin_insecure(self):
"""A POST HTTP request with a good origin is accepted."""
req = self._get_POST_request_with_token()
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'http://www.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "http://www.example.com"
mw = CsrfViewMiddleware(post_form_view)
self.assertIs(mw._origin_verified(req), True)
response = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(response)
- @override_settings(ALLOWED_HOSTS=['www.example.com'])
+ @override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_good_origin_secure(self):
"""A POST HTTPS request with a good origin is accepted."""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'https://www.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "https://www.example.com"
mw = CsrfViewMiddleware(post_form_view)
self.assertIs(mw._origin_verified(req), True)
response = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(response)
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_TRUSTED_ORIGINS=['https://dashboard.example.com'])
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"],
+ CSRF_TRUSTED_ORIGINS=["https://dashboard.example.com"],
+ )
def test_good_origin_csrf_trusted_origin_allowed(self):
"""
A POST request with an origin added to the CSRF_TRUSTED_ORIGINS
@@ -969,16 +1026,19 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'https://dashboard.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "https://dashboard.example.com"
mw = CsrfViewMiddleware(post_form_view)
self.assertIs(mw._origin_verified(req), True)
resp = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(resp)
- self.assertEqual(mw.allowed_origins_exact, {'https://dashboard.example.com'})
+ self.assertEqual(mw.allowed_origins_exact, {"https://dashboard.example.com"})
self.assertEqual(mw.allowed_origin_subdomains, {})
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_TRUSTED_ORIGINS=['https://*.example.com'])
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"],
+ CSRF_TRUSTED_ORIGINS=["https://*.example.com"],
+ )
def test_good_origin_wildcard_csrf_trusted_origin_allowed(self):
"""
A POST request with an origin that matches a CSRF_TRUSTED_ORIGINS
@@ -986,18 +1046,17 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin):
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_HOST'] = 'www.example.com'
- req.META['HTTP_ORIGIN'] = 'https://foo.example.com'
+ req.META["HTTP_HOST"] = "www.example.com"
+ req.META["HTTP_ORIGIN"] = "https://foo.example.com"
mw = CsrfViewMiddleware(post_form_view)
self.assertIs(mw._origin_verified(req), True)
response = mw.process_view(req, post_form_view, (), {})
self.assertIsNone(response)
self.assertEqual(mw.allowed_origins_exact, set())
- self.assertEqual(mw.allowed_origin_subdomains, {'https': ['.example.com']})
+ self.assertEqual(mw.allowed_origin_subdomains, {"https": [".example.com"]})
class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
-
def _set_csrf_cookie(self, req, cookie):
req.COOKIES[settings.CSRF_COOKIE_NAME] = cookie
@@ -1021,7 +1080,7 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
resp = ensure_csrf_cookie_view(req)
csrf_cookie = self._read_csrf_cookie(req, resp)
self.assertTrue(csrf_cookie)
- self.assertIn('Cookie', resp.get('Vary', ''))
+ self.assertIn("Cookie", resp.get("Vary", ""))
def test_ensures_csrf_cookie_with_middleware(self):
"""
@@ -1034,7 +1093,7 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
resp = mw(req)
csrf_cookie = self._read_csrf_cookie(req, resp)
self.assertTrue(csrf_cookie)
- self.assertIn('Cookie', resp.get('Vary', ''))
+ self.assertIn("Cookie", resp.get("Vary", ""))
def test_csrf_cookie_age(self):
"""
@@ -1043,17 +1102,19 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
req = self._get_request()
MAX_AGE = 123
- with self.settings(CSRF_COOKIE_NAME='csrfcookie',
- CSRF_COOKIE_DOMAIN='.example.com',
- CSRF_COOKIE_AGE=MAX_AGE,
- CSRF_COOKIE_PATH='/test/',
- CSRF_COOKIE_SECURE=True,
- CSRF_COOKIE_HTTPONLY=True):
+ with self.settings(
+ CSRF_COOKIE_NAME="csrfcookie",
+ CSRF_COOKIE_DOMAIN=".example.com",
+ CSRF_COOKIE_AGE=MAX_AGE,
+ CSRF_COOKIE_PATH="/test/",
+ CSRF_COOKIE_SECURE=True,
+ CSRF_COOKIE_HTTPONLY=True,
+ ):
# token_view calls get_token() indirectly
mw = CsrfViewMiddleware(token_view)
mw.process_view(req, token_view, (), {})
resp = mw(req)
- max_age = resp.cookies.get('csrfcookie').get('max-age')
+ max_age = resp.cookies.get("csrfcookie").get("max-age")
self.assertEqual(max_age, MAX_AGE)
def test_csrf_cookie_age_none(self):
@@ -1064,47 +1125,53 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
req = self._get_request()
MAX_AGE = None
- with self.settings(CSRF_COOKIE_NAME='csrfcookie',
- CSRF_COOKIE_DOMAIN='.example.com',
- CSRF_COOKIE_AGE=MAX_AGE,
- CSRF_COOKIE_PATH='/test/',
- CSRF_COOKIE_SECURE=True,
- CSRF_COOKIE_HTTPONLY=True):
+ with self.settings(
+ CSRF_COOKIE_NAME="csrfcookie",
+ CSRF_COOKIE_DOMAIN=".example.com",
+ CSRF_COOKIE_AGE=MAX_AGE,
+ CSRF_COOKIE_PATH="/test/",
+ CSRF_COOKIE_SECURE=True,
+ CSRF_COOKIE_HTTPONLY=True,
+ ):
# token_view calls get_token() indirectly
mw = CsrfViewMiddleware(token_view)
mw.process_view(req, token_view, (), {})
resp = mw(req)
- max_age = resp.cookies.get('csrfcookie').get('max-age')
- self.assertEqual(max_age, '')
+ max_age = resp.cookies.get("csrfcookie").get("max-age")
+ self.assertEqual(max_age, "")
def test_csrf_cookie_samesite(self):
req = self._get_request()
- with self.settings(CSRF_COOKIE_NAME='csrfcookie', CSRF_COOKIE_SAMESITE='Strict'):
+ with self.settings(
+ CSRF_COOKIE_NAME="csrfcookie", CSRF_COOKIE_SAMESITE="Strict"
+ ):
mw = CsrfViewMiddleware(token_view)
mw.process_view(req, token_view, (), {})
resp = mw(req)
- self.assertEqual(resp.cookies['csrfcookie']['samesite'], 'Strict')
+ self.assertEqual(resp.cookies["csrfcookie"]["samesite"], "Strict")
def test_bad_csrf_cookie_characters(self):
"""
If the CSRF cookie has invalid characters in a POST request, the
middleware rejects the incoming request.
"""
- self._check_bad_or_missing_cookie(64 * '*', 'CSRF cookie has invalid characters.')
+ 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', 'CSRF cookie has incorrect length.')
+ self._check_bad_or_missing_cookie(16 * "a", "CSRF cookie has incorrect length.")
def test_process_view_token_too_long(self):
"""
If the token is longer than expected, it is ignored and a new token is
created.
"""
- req = self._get_request(cookie='x' * 100000)
+ req = self._get_request(cookie="x" * 100000)
mw = CsrfViewMiddleware(token_view)
mw.process_view(req, token_view, (), {})
resp = mw(req)
@@ -1116,7 +1183,7 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
If the token contains non-alphanumeric characters, it is ignored and a
new token is created.
"""
- token = ('!@#' + self._csrf_id_token)[:CSRF_TOKEN_LENGTH]
+ token = ("!@#" + self._csrf_id_token)[:CSRF_TOKEN_LENGTH]
req = self._get_request(cookie=token)
mw = CsrfViewMiddleware(token_view)
mw.process_view(req, token_view, (), {})
@@ -1145,7 +1212,9 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
with self.subTest(args=args):
cookie, post_token, meta_token = args
req = self._get_POST_csrf_cookie_request(
- cookie=cookie, post_token=post_token, meta_token=meta_token,
+ cookie=cookie,
+ post_token=post_token,
+ meta_token=meta_token,
)
mw = CsrfViewMiddleware(token_view)
mw.process_request(req)
@@ -1159,7 +1228,7 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
"""
req = self._get_POST_request_with_token()
resp = ensured_and_protected_view(req)
- self.assertContains(resp, 'OK')
+ self.assertContains(resp, "OK")
csrf_cookie = self._read_csrf_cookie(req, resp)
self.assertEqual(csrf_cookie, TEST_SECRET)
# set_cookie() was called only once and with the expected secret.
@@ -1170,11 +1239,11 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
"""
A CSRF cookie with the wrong format is replaced during a GET request.
"""
- req = self._get_request(cookie='badvalue')
+ req = self._get_request(cookie="badvalue")
resp = protected_view(req)
- self.assertContains(resp, 'OK')
+ self.assertContains(resp, "OK")
csrf_cookie = self._read_csrf_cookie(req, resp)
- self.assertTrue(csrf_cookie, msg='No CSRF cookie was sent.')
+ self.assertTrue(csrf_cookie, msg="No CSRF cookie was sent.")
self.assertEqual(len(csrf_cookie), CSRF_SECRET_LENGTH)
def test_valid_secret_not_replaced_on_GET(self):
@@ -1189,9 +1258,9 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
with self.subTest(cookie=cookie):
req = self._get_request(cookie=cookie)
resp = protected_view(req)
- self.assertContains(resp, 'OK')
+ self.assertContains(resp, "OK")
csrf_cookie = self._read_csrf_cookie(req, resp)
- self.assertFalse(csrf_cookie, msg='A CSRF cookie was sent.')
+ self.assertFalse(csrf_cookie, msg="A CSRF cookie was sent.")
def test_masked_secret_accepted_and_replaced(self):
"""
@@ -1222,14 +1291,20 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
self.assertEqual(csrf_cookie, TEST_SECRET)
self._check_token_present(resp, csrf_cookie)
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_COOKIE_DOMAIN='.example.com', USE_X_FORWARDED_PORT=True)
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"],
+ CSRF_COOKIE_DOMAIN=".example.com",
+ USE_X_FORWARDED_PORT=True,
+ )
def test_https_good_referer_behind_proxy(self):
"""
A POST HTTPS request is accepted when USE_X_FORWARDED_PORT=True.
"""
self._test_https_good_referer_behind_proxy()
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_COOKIE_DOMAIN='.example.com')
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"], CSRF_COOKIE_DOMAIN=".example.com"
+ )
def test_https_good_referer_matches_cookie_domain(self):
"""
A POST HTTPS request with a good referer should be accepted from a
@@ -1237,7 +1312,9 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
"""
self._test_https_good_referer_matches_cookie_domain()
- @override_settings(ALLOWED_HOSTS=['www.example.com'], CSRF_COOKIE_DOMAIN='.example.com')
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"], CSRF_COOKIE_DOMAIN=".example.com"
+ )
def test_https_good_referer_matches_cookie_domain_with_different_port(self):
"""
A POST HTTPS request with a good referer should be accepted from a
@@ -1245,21 +1322,21 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
"""
self._test_https_good_referer_matches_cookie_domain_with_different_port()
- @override_settings(CSRF_COOKIE_DOMAIN='.example.com', DEBUG=True)
+ @override_settings(CSRF_COOKIE_DOMAIN=".example.com", DEBUG=True)
def test_https_reject_insecure_referer(self):
"""
A POST HTTPS request from an insecure referer should be rejected.
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_REFERER'] = 'http://example.com/'
- req.META['SERVER_PORT'] = '443'
+ req.META["HTTP_REFERER"] = "http://example.com/"
+ req.META["SERVER_PORT"] = "443"
mw = CsrfViewMiddleware(post_form_view)
self._check_referer_rejects(mw, req)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(
response,
- 'Referer checking failed - Referer is insecure while host is secure.',
+ "Referer checking failed - Referer is insecure while host is secure.",
status_code=403,
)
@@ -1286,8 +1363,8 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest
def test_no_session_on_request(self):
msg = (
- 'CSRF_USE_SESSIONS is enabled, but request.session is not set. '
- 'SessionMiddleware must appear before CsrfViewMiddleware in MIDDLEWARE.'
+ "CSRF_USE_SESSIONS is enabled, but request.session is not set. "
+ "SessionMiddleware must appear before CsrfViewMiddleware in MIDDLEWARE."
)
with self.assertRaisesMessage(ImproperlyConfigured, msg):
mw = CsrfViewMiddleware(lambda req: HttpResponse())
@@ -1309,7 +1386,9 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest
with self.subTest(args=args):
cookie, post_token, meta_token = args
req = self._get_POST_csrf_cookie_request(
- cookie=cookie, post_token=post_token, meta_token=meta_token,
+ cookie=cookie,
+ post_token=post_token,
+ meta_token=meta_token,
)
mw = CsrfViewMiddleware(token_view)
mw.process_request(req)
@@ -1349,8 +1428,8 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest
self.assertTrue(csrf_cookie)
@override_settings(
- ALLOWED_HOSTS=['www.example.com'],
- SESSION_COOKIE_DOMAIN='.example.com',
+ ALLOWED_HOSTS=["www.example.com"],
+ SESSION_COOKIE_DOMAIN=".example.com",
USE_X_FORWARDED_PORT=True,
DEBUG=True,
)
@@ -1360,7 +1439,9 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest
"""
self._test_https_good_referer_behind_proxy()
- @override_settings(ALLOWED_HOSTS=['www.example.com'], SESSION_COOKIE_DOMAIN='.example.com')
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"], SESSION_COOKIE_DOMAIN=".example.com"
+ )
def test_https_good_referer_matches_cookie_domain(self):
"""
A POST HTTPS request with a good referer should be accepted from a
@@ -1368,7 +1449,9 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest
"""
self._test_https_good_referer_matches_cookie_domain()
- @override_settings(ALLOWED_HOSTS=['www.example.com'], SESSION_COOKIE_DOMAIN='.example.com')
+ @override_settings(
+ ALLOWED_HOSTS=["www.example.com"], SESSION_COOKIE_DOMAIN=".example.com"
+ )
def test_https_good_referer_matches_cookie_domain_with_different_port(self):
"""
A POST HTTPS request with a good referer should be accepted from a
@@ -1376,34 +1459,34 @@ class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTest
"""
self._test_https_good_referer_matches_cookie_domain_with_different_port()
- @override_settings(SESSION_COOKIE_DOMAIN='.example.com', DEBUG=True)
+ @override_settings(SESSION_COOKIE_DOMAIN=".example.com", DEBUG=True)
def test_https_reject_insecure_referer(self):
"""
A POST HTTPS request from an insecure referer should be rejected.
"""
req = self._get_POST_request_with_token()
req._is_secure_override = True
- req.META['HTTP_REFERER'] = 'http://example.com/'
- req.META['SERVER_PORT'] = '443'
+ req.META["HTTP_REFERER"] = "http://example.com/"
+ req.META["SERVER_PORT"] = "443"
mw = CsrfViewMiddleware(post_form_view)
response = mw.process_view(req, post_form_view, (), {})
self.assertContains(
response,
- 'Referer checking failed - Referer is insecure while host is secure.',
+ "Referer checking failed - Referer is insecure while host is secure.",
status_code=403,
)
-@override_settings(ROOT_URLCONF='csrf_tests.csrf_token_error_handler_urls', DEBUG=False)
+@override_settings(ROOT_URLCONF="csrf_tests.csrf_token_error_handler_urls", DEBUG=False)
class CsrfInErrorHandlingViewsTests(CsrfFunctionTestMixin, SimpleTestCase):
def test_csrf_token_on_404_stays_constant(self):
- response = self.client.get('/does not exist/')
+ response = self.client.get("/does not exist/")
# The error handler returns status code 599.
self.assertEqual(response.status_code, 599)
- token1 = response.content.decode('ascii')
- response = self.client.get('/does not exist/')
+ token1 = response.content.decode("ascii")
+ response = self.client.get("/does not exist/")
self.assertEqual(response.status_code, 599)
- token2 = response.content.decode('ascii')
+ token2 = response.content.decode("ascii")
secret2 = _unmask_cipher_token(token2)
self.assertMaskedSecretCorrect(token1, secret2)
@@ -1413,24 +1496,24 @@ class CsrfCookieMaskedTests(CsrfFunctionTestMixin, SimpleTestCase):
@override_settings(CSRF_COOKIE_MASKED=True)
def test_get_token_csrf_cookie_not_set(self):
request = HttpRequest()
- self.assertNotIn('CSRF_COOKIE', request.META)
- self.assertNotIn('CSRF_COOKIE_NEEDS_UPDATE', request.META)
+ self.assertNotIn("CSRF_COOKIE", request.META)
+ self.assertNotIn("CSRF_COOKIE_NEEDS_UPDATE", request.META)
token = get_token(request)
- cookie = request.META['CSRF_COOKIE']
+ cookie = request.META["CSRF_COOKIE"]
self.assertEqual(len(cookie), CSRF_TOKEN_LENGTH)
unmasked_cookie = _unmask_cipher_token(cookie)
self.assertMaskedSecretCorrect(token, unmasked_cookie)
- self.assertIs(request.META['CSRF_COOKIE_NEEDS_UPDATE'], True)
+ self.assertIs(request.META["CSRF_COOKIE_NEEDS_UPDATE"], True)
@override_settings(CSRF_COOKIE_MASKED=True)
def test_rotate_token(self):
request = HttpRequest()
- request.META['CSRF_COOKIE'] = MASKED_TEST_SECRET1
- self.assertNotIn('CSRF_COOKIE_NEEDS_UPDATE', request.META)
+ request.META["CSRF_COOKIE"] = MASKED_TEST_SECRET1
+ self.assertNotIn("CSRF_COOKIE_NEEDS_UPDATE", request.META)
rotate_token(request)
# The underlying secret was changed.
- cookie = request.META['CSRF_COOKIE']
+ cookie = request.META["CSRF_COOKIE"]
self.assertEqual(len(cookie), CSRF_TOKEN_LENGTH)
unmasked_cookie = _unmask_cipher_token(cookie)
self.assertNotEqual(unmasked_cookie, TEST_SECRET)
- self.assertIs(request.META['CSRF_COOKIE_NEEDS_UPDATE'], True)
+ self.assertIs(request.META["CSRF_COOKIE_NEEDS_UPDATE"], True)
diff --git a/tests/csrf_tests/views.py b/tests/csrf_tests/views.py
index 774d72650d..35c7fb95d6 100644
--- a/tests/csrf_tests/views.py
+++ b/tests/csrf_tests/views.py
@@ -12,6 +12,7 @@ class TestingHttpResponse(HttpResponse):
A version of HttpResponse that stores what cookie values are passed to
set_cookie() when CSRF_USE_SESSIONS=False.
"""
+
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# This is a list of the cookie values passed to set_cookie() over
@@ -24,7 +25,6 @@ class TestingHttpResponse(HttpResponse):
class _CsrfCookieRotator(MiddlewareMixin):
-
def process_response(self, request, response):
rotate_token(request)
return response
@@ -35,18 +35,18 @@ csrf_rotating_token = decorator_from_middleware(_CsrfCookieRotator)
@csrf_protect
def protected_view(request):
- return HttpResponse('OK')
+ return HttpResponse("OK")
@ensure_csrf_cookie
def ensure_csrf_cookie_view(request):
- return HttpResponse('OK')
+ return HttpResponse("OK")
@csrf_protect
@ensure_csrf_cookie
def ensured_and_protected_view(request):
- return TestingHttpResponse('OK')
+ return TestingHttpResponse("OK")
@csrf_protect
@@ -57,26 +57,28 @@ def sandwiched_rotate_token_view(request):
This is a view that calls rotate_token() in process_response() between two
calls to CsrfViewMiddleware.process_response().
"""
- return TestingHttpResponse('OK')
+ return TestingHttpResponse("OK")
def post_form_view(request):
"""Return a POST form (without a token)."""
- return HttpResponse(content="""
+ return HttpResponse(
+ content="""
<html><body><h1>\u00a1Unicode!<form method="post"><input type="text"></form></body></html>
-""")
+"""
+ )
def token_view(request):
context = RequestContext(request, processors=[csrf])
- template = Template('{% csrf_token %}')
+ template = Template("{% csrf_token %}")
return HttpResponse(template.render(context))
def non_token_view_using_request_processor(request):
"""Use the csrf view processor instead of the token."""
context = RequestContext(request, processors=[csrf])
- template = Template('')
+ template = Template("")
return HttpResponse(template.render(context))