summaryrefslogtreecommitdiff
path: root/tests/auth_tests/test_remote_user.py
diff options
context:
space:
mode:
authorColton Hicks <coltonbhicks@gmail.com>2020-01-31 23:42:24 -0800
committerCarlton Gibson <carlton@noumenal.es>2020-02-26 17:25:20 +0100
commitf283ffaa84ef0a558eb466b8fc3fae7e6fbb547c (patch)
tree5ce717580435c427520bc64b6bcb954ffef63ceb /tests/auth_tests/test_remote_user.py
parentbc1c03407649a37a8a3c26b8d0cb355ab2fc128e (diff)
Fixed #28699 -- Fixed CSRF validation with remote user middleware.
Ensured process_view() always accesses the CSRF token from the session or cookie, rather than the request, as rotate_token() may have been called by an authentication middleware during the process_request() phase.
Diffstat (limited to 'tests/auth_tests/test_remote_user.py')
-rw-r--r--tests/auth_tests/test_remote_user.py32
1 files changed, 31 insertions, 1 deletions
diff --git a/tests/auth_tests/test_remote_user.py b/tests/auth_tests/test_remote_user.py
index 6260c460af..ee1f2e1cdf 100644
--- a/tests/auth_tests/test_remote_user.py
+++ b/tests/auth_tests/test_remote_user.py
@@ -5,7 +5,8 @@ from django.contrib.auth import authenticate
from django.contrib.auth.backends import RemoteUserBackend
from django.contrib.auth.middleware import RemoteUserMiddleware
from django.contrib.auth.models import User
-from django.test import TestCase, modify_settings, override_settings
+from django.middleware.csrf import _get_new_csrf_string, _mask_cipher_secret
+from django.test import Client, TestCase, modify_settings, override_settings
from django.utils import timezone
@@ -50,6 +51,35 @@ class RemoteUserTest(TestCase):
self.assertTrue(response.context['user'].is_anonymous)
self.assertEqual(User.objects.count(), num_users)
+ def test_csrf_validation_passes_after_process_request_login(self):
+ """
+ CSRF check must access the CSRF token from the session or cookie,
+ rather than the request, as rotate_token() may have been called by an
+ authentication middleware during the process_request() phase.
+ """
+ csrf_client = Client(enforce_csrf_checks=True)
+ csrf_secret = _get_new_csrf_string()
+ csrf_token = _mask_cipher_secret(csrf_secret)
+ csrf_token_form = _mask_cipher_secret(csrf_secret)
+ headers = {self.header: 'fakeuser'}
+ data = {'csrfmiddlewaretoken': csrf_token_form}
+
+ # Verify that CSRF is configured for the view
+ csrf_client.cookies.load({settings.CSRF_COOKIE_NAME: csrf_token})
+ response = csrf_client.post('/remote_user/', **headers)
+ self.assertEqual(response.status_code, 403)
+ self.assertIn(b'CSRF verification failed.', response.content)
+
+ # This request will call django.contrib.auth.login() which will call
+ # django.middleware.csrf.rotate_token() thus changing the value of
+ # request.META['CSRF_COOKIE'] from the user submitted value set by
+ # CsrfViewMiddleware.process_request() to the new csrftoken value set
+ # by rotate_token(). Csrf validation should still pass when the view is
+ # later processed by CsrfViewMiddleware.process_view()
+ csrf_client.cookies.load({settings.CSRF_COOKIE_NAME: csrf_token})
+ response = csrf_client.post('/remote_user/', data, **headers)
+ self.assertEqual(response.status_code, 200)
+
def test_unknown_user(self):
"""
Tests the case where the username passed in the header does not exist