Loading django/contrib/auth/__init__.py +2 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ import re from django.conf import settings from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.utils.module_loading import import_by_path from django.middleware.csrf import rotate_token from .signals import user_logged_in, user_logged_out, user_login_failed Loading Loading @@ -84,6 +85,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/test_views.py +39 −1 Original line number Diff line number Diff line Loading @@ -12,18 +12,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 @@ -460,6 +463,41 @@ class LoginTest(AuthViewsTestCase): # the custom authentication form used by this login asserts # that a request is passed to the form successfully. 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 @@ -3,6 +3,7 @@ import re from django.conf import settings from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.utils.module_loading import import_by_path from django.middleware.csrf import rotate_token from .signals import user_logged_in, user_logged_out, user_login_failed Loading Loading @@ -84,6 +85,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/test_views.py +39 −1 Original line number Diff line number Diff line Loading @@ -12,18 +12,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 @@ -460,6 +463,41 @@ class LoginTest(AuthViewsTestCase): # the custom authentication form used by this login asserts # that a request is passed to the form successfully. 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