From 7549eb000430192833f05186056d1ae20b0d17ad Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 15 Aug 2016 19:29:12 -0400 Subject: [PATCH] Fixed #27009 -- Made update_session_auth_hash() rotate the session key. --- django/contrib/auth/__init__.py | 1 + docs/releases/1.11.txt | 3 +++ docs/topics/auth/default.txt | 14 +++++++++----- tests/auth_tests/test_views.py | 3 +++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index 6f2a2e45c3..fa0ef39a32 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -215,6 +215,7 @@ def update_session_auth_hash(request, user): appropriately to prevent a password change from logging out the session from which the password was changed. """ + request.session.cycle_key() if hasattr(user, 'get_session_auth_hash') and request.user == user: request.session[HASH_SESSION_KEY] = user.get_session_auth_hash() diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt index 96bb998887..57cda8ae8b 100644 --- a/docs/releases/1.11.txt +++ b/docs/releases/1.11.txt @@ -84,6 +84,9 @@ Minor features :class:`~django.contrib.auth.views.PasswordResetConfirmView` allows automatically logging in a user after a successful password reset. +* :func:`~django.contrib.auth.update_session_auth_hash` now rotates the session + key to allow a password change to invalidate stolen session cookies. + :mod:`django.contrib.contenttypes` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 6735c261df..f8a1a50169 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -841,16 +841,16 @@ The default password change views included with Django, the session with the new password hash so that a user changing their own password won't log themselves out. If you have a custom password change view and wish to have similar behavior, use the :func:`update_session_auth_hash` -function. In this case, however, if a user also wants to invalidate the session -from which they're changing their password (for example, if they believe the -session cookie on their machine was stolen), then they also need to log out -that session. +function. .. function:: update_session_auth_hash(request, user) This function takes the current request and the updated user object from which the new session hash will be derived and updates the session hash - appropriately. Example usage:: + appropriately. It also rotates the session key so that a stolen session + cookie will be invalidated. + + Example usage:: from django.contrib.auth import update_session_auth_hash @@ -863,6 +863,10 @@ that session. else: ... + .. versionchanged:: 1.11 + + Rotating of the session key was added. + .. note:: Since diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index 3ae0bf4b89..e3b1bd9f5b 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -479,6 +479,7 @@ class SessionAuthenticationTests(AuthViewsTestCase): session auth hash after a password change so the session isn't logged out. """ self.login() + original_session_key = self.client.session.session_key response = self.client.post('/password_change/', { 'old_password': 'password', 'new_password1': 'password1', @@ -486,6 +487,8 @@ class SessionAuthenticationTests(AuthViewsTestCase): }) # if the hash isn't updated, retrieving the redirection page will fail. self.assertRedirects(response, '/password_change/done/') + # The session key is rotated. + self.assertNotEqual(original_session_key, self.client.session.session_key) class LoginTest(AuthViewsTestCase):