Loading django/contrib/auth/__init__.py +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import re from django.core.exceptions import ImproperlyConfigured from django.utils.importlib import import_module from django.middleware.csrf import rotate_token from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed SESSION_KEY = '_auth_user_id' Loading Loading @@ -92,6 +93,7 @@ def login(request, user): request.session[BACKEND_SESSION_KEY] = user.backend if hasattr(request, 'user'): request.user = user rotate_token(request) user_logged_in.send(sender=user.__class__, request=request, user=user) Loading django/contrib/auth/tests/views.py +39 −1 Original line number Diff line number Diff line Loading @@ -7,18 +7,21 @@ from django.contrib.auth.models import User from django.core import mail from django.core.exceptions import SuspiciousOperation from django.core.urlresolvers import reverse, NoReverseMatch from django.http import QueryDict from django.http import QueryDict, HttpRequest from django.utils.encoding import force_text from django.utils.html import escape from django.utils.http import urlquote from django.utils._os import upath from django.test import TestCase from django.test.utils import override_settings from django.middleware.csrf import CsrfViewMiddleware from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME from django.contrib.auth.forms import (AuthenticationForm, PasswordChangeForm, SetPasswordForm, PasswordResetForm) from django.contrib.auth.tests.utils import skipIfCustomUser from django.contrib.auth.views import login as login_view @override_settings( Loading Loading @@ -361,6 +364,41 @@ class LoginTest(AuthViewsTestCase): self.assertTrue(good_url in response['Location'], "%s should be allowed" % good_url) def test_login_csrf_rotate(self, password='password'): """ Makes sure that a login rotates the currently-used CSRF token. """ # Do a GET to establish a CSRF token # TestClient isn't used here as we're testing middleware, essentially. req = HttpRequest() CsrfViewMiddleware().process_view(req, login_view, (), {}) req.META["CSRF_COOKIE_USED"] = True resp = login_view(req) resp2 = CsrfViewMiddleware().process_response(req, resp) csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, None) token1 = csrf_cookie.coded_value # Prepare the POST request req = HttpRequest() req.COOKIES[settings.CSRF_COOKIE_NAME] = token1 req.method = "POST" req.POST = {'username': 'testclient', 'password': password, 'csrfmiddlewaretoken': token1} req.REQUEST = req.POST # Use POST request to log in SessionMiddleware().process_request(req) CsrfViewMiddleware().process_view(req, login_view, (), {}) req.META["SERVER_NAME"] = "testserver" # Required to have redirect work in login view req.META["SERVER_PORT"] = 80 req.META["CSRF_COOKIE_USED"] = True resp = login_view(req) resp2 = CsrfViewMiddleware().process_response(req, resp) csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, None) token2 = csrf_cookie.coded_value # Check the CSRF token switched self.assertNotEqual(token1, token2) @skipIfCustomUser class LoginURLSettings(AuthViewsTestCase): Loading django/middleware/csrf.py +8 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,14 @@ def get_token(request): return request.META.get("CSRF_COOKIE", None) def rotate_token(request): """ Changes the CSRF token in use for a request - should be done on login for security purposes. """ request.META["CSRF_COOKIE"] = _get_new_csrf_key() def _sanitize_token(token): # Allow only alphanum if len(token) > CSRF_KEY_LENGTH: Loading Loading
django/contrib/auth/__init__.py +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import re from django.core.exceptions import ImproperlyConfigured from django.utils.importlib import import_module from django.middleware.csrf import rotate_token from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed SESSION_KEY = '_auth_user_id' Loading Loading @@ -92,6 +93,7 @@ def login(request, user): request.session[BACKEND_SESSION_KEY] = user.backend if hasattr(request, 'user'): request.user = user rotate_token(request) user_logged_in.send(sender=user.__class__, request=request, user=user) Loading
django/contrib/auth/tests/views.py +39 −1 Original line number Diff line number Diff line Loading @@ -7,18 +7,21 @@ from django.contrib.auth.models import User from django.core import mail from django.core.exceptions import SuspiciousOperation from django.core.urlresolvers import reverse, NoReverseMatch from django.http import QueryDict from django.http import QueryDict, HttpRequest from django.utils.encoding import force_text from django.utils.html import escape from django.utils.http import urlquote from django.utils._os import upath from django.test import TestCase from django.test.utils import override_settings from django.middleware.csrf import CsrfViewMiddleware from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME from django.contrib.auth.forms import (AuthenticationForm, PasswordChangeForm, SetPasswordForm, PasswordResetForm) from django.contrib.auth.tests.utils import skipIfCustomUser from django.contrib.auth.views import login as login_view @override_settings( Loading Loading @@ -361,6 +364,41 @@ class LoginTest(AuthViewsTestCase): self.assertTrue(good_url in response['Location'], "%s should be allowed" % good_url) def test_login_csrf_rotate(self, password='password'): """ Makes sure that a login rotates the currently-used CSRF token. """ # Do a GET to establish a CSRF token # TestClient isn't used here as we're testing middleware, essentially. req = HttpRequest() CsrfViewMiddleware().process_view(req, login_view, (), {}) req.META["CSRF_COOKIE_USED"] = True resp = login_view(req) resp2 = CsrfViewMiddleware().process_response(req, resp) csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, None) token1 = csrf_cookie.coded_value # Prepare the POST request req = HttpRequest() req.COOKIES[settings.CSRF_COOKIE_NAME] = token1 req.method = "POST" req.POST = {'username': 'testclient', 'password': password, 'csrfmiddlewaretoken': token1} req.REQUEST = req.POST # Use POST request to log in SessionMiddleware().process_request(req) CsrfViewMiddleware().process_view(req, login_view, (), {}) req.META["SERVER_NAME"] = "testserver" # Required to have redirect work in login view req.META["SERVER_PORT"] = 80 req.META["CSRF_COOKIE_USED"] = True resp = login_view(req) resp2 = CsrfViewMiddleware().process_response(req, resp) csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, None) token2 = csrf_cookie.coded_value # Check the CSRF token switched self.assertNotEqual(token1, token2) @skipIfCustomUser class LoginURLSettings(AuthViewsTestCase): Loading
django/middleware/csrf.py +8 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,14 @@ def get_token(request): return request.META.get("CSRF_COOKIE", None) def rotate_token(request): """ Changes the CSRF token in use for a request - should be done on login for security purposes. """ request.META["CSRF_COOKIE"] = _get_new_csrf_key() def _sanitize_token(token): # Allow only alphanum if len(token) > CSRF_KEY_LENGTH: Loading