diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/csrf_tests/tests.py | 493 |
1 files changed, 304 insertions, 189 deletions
diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index cd7ea8fbc6..6369de9f99 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -6,10 +6,12 @@ import re import warnings from django.conf import settings +from django.core.exceptions import ImproperlyConfigured from django.http import HttpRequest, HttpResponse from django.middleware.csrf import ( - CSRF_TOKEN_LENGTH, REASON_BAD_TOKEN, REASON_NO_CSRF_COOKIE, - CsrfViewMiddleware, _compare_salted_tokens as equivalent_tokens, get_token, + CSRF_SESSION_KEY, CSRF_TOKEN_LENGTH, REASON_BAD_TOKEN, + REASON_NO_CSRF_COOKIE, CsrfViewMiddleware, + _compare_salted_tokens as equivalent_tokens, get_token, ) from django.template import RequestContext, Template from django.template.context_processors import csrf @@ -58,20 +60,27 @@ class TestingHttpRequest(HttpRequest): A version of HttpRequest that allows us to change some things more easily """ + def __init__(self): + super(TestingHttpRequest, self).__init__() + # A real session backend isn't needed. + self.session = {} + def is_secure(self): return getattr(self, '_is_secure_override', False) -class CsrfViewMiddlewareTest(SimpleTestCase): +class CsrfViewMiddlewareTestMixin(object): + """ + Shared methods and tests for session-based and cookie-based tokens. + """ + _csrf_id = _csrf_id_cookie = '1bcdefghij2bcdefghij3bcdefghij4bcdefghij5bcdefghij6bcdefghijABCD' def _get_GET_no_csrf_cookie_request(self): return TestingHttpRequest() def _get_GET_csrf_cookie_request(self): - req = TestingHttpRequest() - req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id_cookie - return req + raise NotImplementedError('This method must be implemented by a subclass.') def _get_POST_csrf_cookie_request(self): req = self._get_GET_csrf_cookie_request() @@ -88,16 +97,6 @@ class CsrfViewMiddlewareTest(SimpleTestCase): req.POST['csrfmiddlewaretoken'] = self._csrf_id return req - def _get_POST_bare_secret_csrf_cookie_request(self): - req = self._get_POST_no_csrf_cookie_request() - req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id_cookie[:32] - return req - - def _get_POST_bare_secret_csrf_cookie_request_with_token(self): - req = self._get_POST_bare_secret_csrf_cookie_request() - req.POST['csrfmiddlewaretoken'] = self._csrf_id_cookie[:32] - return req - def _check_token_present(self, response, csrf_id=None): text = text_type(response.content, response.charset) match = re.search("name='csrfmiddlewaretoken' value='(.*?)'", text) @@ -107,77 +106,6 @@ class CsrfViewMiddlewareTest(SimpleTestCase): "Could not find csrfmiddlewaretoken to match %s" % csrf_token ) - 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_GET_no_csrf_cookie_request() - req.COOKIES[settings.CSRF_COOKIE_NAME] = 'x' * 100000 - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) - - def test_process_view_token_invalid_chars(self): - """ - If the token contains non-alphanumeric characters, it is ignored and a - new token is created. - """ - token = ('!@#' + self._csrf_id)[:CSRF_TOKEN_LENGTH] - req = self._get_GET_no_csrf_cookie_request() - req.COOKIES[settings.CSRF_COOKIE_NAME] = token - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) - self.assertNotEqual(csrf_cookie.value, token) - - def test_process_view_token_invalid_bytes(self): - """ - If the token contains improperly encoded unicode, it is ignored and a - new token is created. - """ - token = (b"<1>\xc2\xa1" + force_bytes(self._csrf_id, 'ascii'))[:CSRF_TOKEN_LENGTH] - req = self._get_GET_no_csrf_cookie_request() - req.COOKIES[settings.CSRF_COOKIE_NAME] = token - # We expect a UnicodeWarning here, because we used broken utf-8 on purpose - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=UnicodeWarning) - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) - self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) - self.assertNotEqual(csrf_cookie.value, token) - - def test_process_response_get_token_used(self): - """ - When get_token is used, check that the cookie is created and headers - patched. - """ - req = self._get_GET_no_csrf_cookie_request() - - # Put tests for CSRF_COOKIE_* settings here - with self.settings(CSRF_COOKIE_NAME='myname', - CSRF_COOKIE_DOMAIN='.example.com', - CSRF_COOKIE_PATH='/test/', - CSRF_COOKIE_SECURE=True, - CSRF_COOKIE_HTTPONLY=True): - # token_view calls get_token() indirectly - CsrfViewMiddleware().process_view(req, token_view, (), {}) - resp = token_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get('myname', False) - self.assertIsNot(csrf_cookie, False) - self.assertEqual(csrf_cookie['domain'], '.example.com') - self.assertIs(csrf_cookie['secure'], True) - self.assertIs(csrf_cookie['httponly'], True) - self.assertEqual(csrf_cookie['path'], '/test/') - self.assertIn('Cookie', resp2.get('Vary', '')) - def test_process_response_get_token_not_used(self): """ If get_token() is not called, the view middleware does not @@ -371,20 +299,6 @@ class CsrfViewMiddlewareTest(SimpleTestCase): "CSRF cookie was changed on an accepted request" ) - def test_bare_secret_accepted_and_replaced(self): - """ - The csrf token is reset from a bare secret. - """ - req = self._get_POST_bare_secret_csrf_cookie_request_with_token() - req2 = CsrfViewMiddleware().process_view(req, token_view, (), {}) - self.assertIsNone(req2) - resp = token_view(req) - resp = CsrfViewMiddleware().process_response(req, resp) - self.assertIn(settings.CSRF_COOKIE_NAME, resp.cookies, "Cookie was not reset from bare secret") - csrf_cookie = resp.cookies[settings.CSRF_COOKIE_NAME] - self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) - self._check_token_present(resp, csrf_id=csrf_cookie.value) - @override_settings(DEBUG=True, ALLOWED_HOSTS=['www.example.com']) def test_https_bad_referer(self): """ @@ -465,11 +379,7 @@ class CsrfViewMiddlewareTest(SimpleTestCase): req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) self.assertIsNone(req2) - @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. - """ + def _test_https_good_referer_behind_proxy(self): req = self._get_POST_request_with_token() req._is_secure_override = True req.META.update({ @@ -508,12 +418,7 @@ class CsrfViewMiddlewareTest(SimpleTestCase): response = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) self.assertIsNone(response) - @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 - subdomain that's allowed by CSRF_COOKIE_DOMAIN. - """ + 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/' @@ -521,12 +426,7 @@ class CsrfViewMiddlewareTest(SimpleTestCase): response = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) self.assertIsNone(response) - @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 - subdomain that's allowed by CSRF_COOKIE_DOMAIN and a non-443 port. - """ + 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' @@ -535,21 +435,98 @@ class CsrfViewMiddlewareTest(SimpleTestCase): response = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) self.assertIsNone(response) - @override_settings(CSRF_COOKIE_DOMAIN='.example.com', DEBUG=True) - def test_https_reject_insecure_referer(self): + def test_ensures_csrf_cookie_no_logging(self): """ - A POST HTTPS request from an insecure referer should be rejected. + ensure_csrf_cookie() doesn't log warnings (#19436). """ - req = self._get_POST_request_with_token() - req._is_secure_override = True - req.META['HTTP_REFERER'] = 'http://example.com/' - req.META['SERVER_PORT'] = '443' - response = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) - self.assertContains( - response, - 'Referer checking failed - Referer is insecure while host is secure.', - status_code=403, - ) + @ensure_csrf_cookie + def view(request): + # Doesn't insert a token or anything + return HttpResponse(content="") + + class TestHandler(logging.Handler): + def emit(self, record): + raise Exception("This shouldn't have happened!") + + logger = logging.getLogger('django.request') + test_handler = TestHandler() + old_log_level = logger.level + try: + logger.addHandler(test_handler) + logger.setLevel(logging.WARNING) + + req = self._get_GET_no_csrf_cookie_request() + view(req) + finally: + logger.removeHandler(test_handler) + logger.setLevel(old_log_level) + + def test_post_data_read_failure(self): + """ + #20128 -- IOErrors during POST data reading should be caught and + treated as if the POST data wasn't there. + """ + class CsrfPostRequest(HttpRequest): + """ + HttpRequest that can raise an IOError when accessing POST data + """ + def __init__(self, token, raise_error): + super(CsrfPostRequest, self).__init__() + self.method = 'POST' + + self.raise_error = False + self.COOKIES[settings.CSRF_COOKIE_NAME] = token + + # Handle both cases here to prevent duplicate code in the + # session tests. + self.session = {} + self.session[CSRF_SESSION_KEY] = token + + self.POST['csrfmiddlewaretoken'] = token + self.raise_error = raise_error + + def _load_post_and_files(self): + raise IOError('error reading input data') + + def _get_post(self): + if self.raise_error: + self._load_post_and_files() + return self._post + + def _set_post(self, post): + self._post = post + + POST = property(_get_post, _set_post) + + token = ('ABC' + self._csrf_id)[:CSRF_TOKEN_LENGTH] + + req = CsrfPostRequest(token, raise_error=False) + resp = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) + self.assertIsNone(resp) + + req = CsrfPostRequest(token, raise_error=True) + with patch_logger('django.security.csrf', 'warning') as logger_calls: + resp = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) + self.assertEqual(resp.status_code, 403) + self.assertEqual(logger_calls[0], 'Forbidden (%s): ' % REASON_BAD_TOKEN) + + +class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase): + + def _get_GET_csrf_cookie_request(self): + req = TestingHttpRequest() + req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id_cookie + return req + + def _get_POST_bare_secret_csrf_cookie_request(self): + req = self._get_POST_no_csrf_cookie_request() + req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id_cookie[:32] + return req + + def _get_POST_bare_secret_csrf_cookie_request_with_token(self): + req = self._get_POST_bare_secret_csrf_cookie_request() + req.POST['csrfmiddlewaretoken'] = self._csrf_id_cookie[:32] + return req def test_ensures_csrf_cookie_no_middleware(self): """ @@ -582,32 +559,6 @@ class CsrfViewMiddlewareTest(SimpleTestCase): self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)) self.assertIn('Cookie', resp2.get('Vary', '')) - def test_ensures_csrf_cookie_no_logging(self): - """ - ensure_csrf_cookie() doesn't log warnings (#19436). - """ - @ensure_csrf_cookie - def view(request): - # Doesn't insert a token or anything - return HttpResponse(content="") - - class TestHandler(logging.Handler): - def emit(self, record): - raise Exception("This shouldn't have happened!") - - logger = logging.getLogger('django.request') - test_handler = TestHandler() - old_log_level = logger.level - try: - logger.addHandler(test_handler) - logger.setLevel(logging.WARNING) - - req = self._get_GET_no_csrf_cookie_request() - view(req) - finally: - logger.removeHandler(test_handler) - logger.setLevel(old_log_level) - def test_csrf_cookie_age(self): """ CSRF cookie age can be set using settings.CSRF_COOKIE_AGE. @@ -651,45 +602,209 @@ class CsrfViewMiddlewareTest(SimpleTestCase): max_age = resp2.cookies.get('csrfcookie').get('max-age') self.assertEqual(max_age, '') - def test_post_data_read_failure(self): + def test_process_view_token_too_long(self): """ - #20128 -- IOErrors during POST data reading should be caught and - treated as if the POST data wasn't there. + If the token is longer than expected, it is ignored and a new token is + created. """ - class CsrfPostRequest(HttpRequest): - """ - HttpRequest that can raise an IOError when accessing POST data - """ - def __init__(self, token, raise_error): - super(CsrfPostRequest, self).__init__() - self.method = 'POST' + req = self._get_GET_no_csrf_cookie_request() + req.COOKIES[settings.CSRF_COOKIE_NAME] = 'x' * 100000 + CsrfViewMiddleware().process_view(req, token_view, (), {}) + resp = token_view(req) + resp2 = CsrfViewMiddleware().process_response(req, resp) + csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) + self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) - self.raise_error = False - self.COOKIES[settings.CSRF_COOKIE_NAME] = token - self.POST['csrfmiddlewaretoken'] = token - self.raise_error = raise_error + def test_process_view_token_invalid_bytes(self): + """ + If the token contains improperly encoded unicode, it is ignored and a + new token is created. + """ + token = (b"<1>\xc2\xa1" + force_bytes(self._csrf_id, 'ascii'))[:CSRF_TOKEN_LENGTH] + req = self._get_GET_no_csrf_cookie_request() + req.COOKIES[settings.CSRF_COOKIE_NAME] = token + # We expect a UnicodeWarning here, because we used broken utf-8 on purpose + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UnicodeWarning) + CsrfViewMiddleware().process_view(req, token_view, (), {}) + resp = token_view(req) + resp2 = CsrfViewMiddleware().process_response(req, resp) + csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) + self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) + self.assertNotEqual(csrf_cookie.value, token) - def _load_post_and_files(self): - raise IOError('error reading input data') + def test_process_view_token_invalid_chars(self): + """ + If the token contains non-alphanumeric characters, it is ignored and a + new token is created. + """ + token = ('!@#' + self._csrf_id)[:CSRF_TOKEN_LENGTH] + req = self._get_GET_no_csrf_cookie_request() + req.COOKIES[settings.CSRF_COOKIE_NAME] = token + CsrfViewMiddleware().process_view(req, token_view, (), {}) + resp = token_view(req) + resp2 = CsrfViewMiddleware().process_response(req, resp) + csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) + self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) + self.assertNotEqual(csrf_cookie.value, token) - def _get_post(self): - if self.raise_error: - self._load_post_and_files() - return self._post + def test_bare_secret_accepted_and_replaced(self): + """ + The csrf token is reset from a bare secret. + """ + req = self._get_POST_bare_secret_csrf_cookie_request_with_token() + req2 = CsrfViewMiddleware().process_view(req, token_view, (), {}) + self.assertIsNone(req2) + resp = token_view(req) + resp = CsrfViewMiddleware().process_response(req, resp) + self.assertIn(settings.CSRF_COOKIE_NAME, resp.cookies, "Cookie was not reset from bare secret") + csrf_cookie = resp.cookies[settings.CSRF_COOKIE_NAME] + self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH) + self._check_token_present(resp, csrf_id=csrf_cookie.value) - def _set_post(self, post): - self._post = post + @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() - POST = property(_get_post, _set_post) + @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 + subdomain that's allowed by CSRF_COOKIE_DOMAIN. + """ + self._test_https_good_referer_matches_cookie_domain() - token = ('ABC' + self._csrf_id)[:CSRF_TOKEN_LENGTH] + @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 + subdomain that's allowed by CSRF_COOKIE_DOMAIN and a non-443 port. + """ + self._test_https_good_referer_matches_cookie_domain_with_different_port() - req = CsrfPostRequest(token, raise_error=False) - resp = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) - self.assertIsNone(resp) + @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' + response = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) + self.assertContains( + response, + 'Referer checking failed - Referer is insecure while host is secure.', + status_code=403, + ) - req = CsrfPostRequest(token, raise_error=True) - with patch_logger('django.security.csrf', 'warning') as logger_calls: - resp = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) - self.assertEqual(resp.status_code, 403) - self.assertEqual(logger_calls[0], 'Forbidden (%s): ' % REASON_BAD_TOKEN) + +@override_settings(CSRF_USE_SESSIONS=True, CSRF_COOKIE_DOMAIN=None) +class CsrfViewMiddlewareUseSessionsTests(CsrfViewMiddlewareTestMixin, SimpleTestCase): + """ + CSRF tests with CSRF_USE_SESSIONS=True. + """ + + def _get_POST_bare_secret_csrf_cookie_request(self): + req = self._get_POST_no_csrf_cookie_request() + req.session[CSRF_SESSION_KEY] = self._csrf_id_cookie[:32] + return req + + def _get_GET_csrf_cookie_request(self): + req = TestingHttpRequest() + req.session[CSRF_SESSION_KEY] = self._csrf_id_cookie + return req + + 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.' + ) + with self.assertRaisesMessage(ImproperlyConfigured, msg): + CsrfViewMiddleware().process_view(HttpRequest(), None, (), {}) + + def test_process_response_get_token_used(self): + """The ensure_csrf_cookie() decorator works without middleware.""" + @ensure_csrf_cookie + def view(request): + # Doesn't insert a token or anything + return HttpResponse(content="") + + req = self._get_GET_no_csrf_cookie_request() + view(req) + self.assertTrue(req.session.get(CSRF_SESSION_KEY, False)) + + def test_ensures_csrf_cookie_with_middleware(self): + """ + The ensure_csrf_cookie() decorator works with the CsrfViewMiddleware + enabled. + """ + @ensure_csrf_cookie + def view(request): + # Doesn't insert a token or anything + return HttpResponse(content="") + + req = self._get_GET_no_csrf_cookie_request() + CsrfViewMiddleware().process_view(req, view, (), {}) + resp = view(req) + CsrfViewMiddleware().process_response(req, resp) + self.assertTrue(req.session.get(CSRF_SESSION_KEY, False)) + + def test_token_node_with_new_csrf_cookie(self): + """ + CsrfTokenNode works when a CSRF cookie is created by the middleware + (when one was not already present). + """ + req = self._get_GET_no_csrf_cookie_request() + CsrfViewMiddleware().process_view(req, token_view, (), {}) + resp = token_view(req) + CsrfViewMiddleware().process_response(req, resp) + csrf_cookie = req.session[CSRF_SESSION_KEY] + self._check_token_present(resp, csrf_id=csrf_cookie) + + @override_settings( + ALLOWED_HOSTS=['www.example.com'], + SESSION_COOKIE_DOMAIN='.example.com', + USE_X_FORWARDED_PORT=True, + DEBUG=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'], 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 + subdomain that's allowed by SESSION_COOKIE_DOMAIN. + """ + self._test_https_good_referer_matches_cookie_domain() + + @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 + subdomain that's allowed by SESSION_COOKIE_DOMAIN and a non-443 port. + """ + self._test_https_good_referer_matches_cookie_domain_with_different_port() + + @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' + response = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) + self.assertContains( + response, + 'Referer checking failed - Referer is insecure while host is secure.', + status_code=403, + ) |
