Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1a45d05

Browse files
ptonetimgraham
authored andcommitted
[1.7.x] Fixed #23066 -- Modified RemoteUserMiddleware to logout on REMOTE_USER change.
This is a security fix. Disclosure following shortly.
1 parent 3123f84 commit 1a45d05

File tree

5 files changed

+65
-8
lines changed

5 files changed

+65
-8
lines changed

django/contrib/auth/middleware.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,19 @@ def process_request(self, request):
7676
# authenticated remote-user, or return (leaving request.user set to
7777
# AnonymousUser by the AuthenticationMiddleware).
7878
if request.user.is_authenticated():
79-
try:
80-
stored_backend = load_backend(request.session.get(
81-
auth.BACKEND_SESSION_KEY, ''))
82-
if isinstance(stored_backend, RemoteUserBackend):
83-
auth.logout(request)
84-
except ImportError:
85-
# backend failed to load
86-
auth.logout(request)
79+
self._remove_invalid_user(request)
8780
return
8881
# If the user is already authenticated and that user is the user we are
8982
# getting passed in the headers, then the correct user is already
9083
# persisted in the session and we don't need to continue.
9184
if request.user.is_authenticated():
9285
if request.user.get_username() == self.clean_username(username, request):
9386
return
87+
else:
88+
# An authenticated user is associated with the request, but
89+
# it does not match the authorized user in the header.
90+
self._remove_invalid_user(request)
91+
9492
# We are seeing this user for the first time in this session, attempt
9593
# to authenticate the user.
9694
user = auth.authenticate(remote_user=username)
@@ -112,3 +110,17 @@ def clean_username(self, username, request):
112110
except AttributeError: # Backend has no clean_username method.
113111
pass
114112
return username
113+
114+
def _remove_invalid_user(self, request):
115+
"""
116+
Removes the current authenticated user in the request which is invalid
117+
but only if the user is authenticated via the RemoteUserBackend.
118+
"""
119+
try:
120+
stored_backend = load_backend(request.session.get(auth.BACKEND_SESSION_KEY, ''))
121+
except ImportError:
122+
# backend failed to load
123+
auth.logout(request)
124+
else:
125+
if isinstance(stored_backend, RemoteUserBackend):
126+
auth.logout(request)

django/contrib/auth/tests/test_remote_user.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ def test_header_disappears(self):
125125
response = self.client.get('/remote_user/')
126126
self.assertEqual(response.context['user'].username, 'modeluser')
127127

128+
def test_user_switch_forces_new_login(self):
129+
"""
130+
Tests that if the username in the header changes between requests
131+
that the original user is logged out
132+
"""
133+
User.objects.create(username='knownuser')
134+
# Known user authenticates
135+
response = self.client.get('/remote_user/',
136+
**{self.header: self.known_user})
137+
self.assertEqual(response.context['user'].username, 'knownuser')
138+
# During the session, the REMOTE_USER changes to a different user.
139+
response = self.client.get('/remote_user/',
140+
**{self.header: "newnewuser"})
141+
# Ensure that the current user is not the prior remote_user
142+
# In backends that create a new user, username is "newnewuser"
143+
# In backends that do not create new users, it is '' (anonymous user)
144+
self.assertNotEqual(response.context['user'].username, 'knownuser')
145+
128146
def tearDown(self):
129147
"""Restores settings to avoid breaking other tests."""
130148
settings.MIDDLEWARE_CLASSES = self.curr_middleware

docs/releases/1.4.14.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,12 @@ if a file with the uploaded name already exists.
3838
underscore plus a random 7 character alphanumeric string (e.g. ``"_x3a1gho"``),
3939
rather than iterating through an underscore followed by a number (e.g. ``"_1"``,
4040
``"_2"``, etc.).
41+
42+
``RemoteUserMiddleware`` session hijacking
43+
==========================================
44+
45+
When using the :class:`~django.contrib.auth.middleware.RemoteUserMiddleware`
46+
and the ``RemoteUserBackend``, a change to the ``REMOTE_USER`` header between
47+
requests without an intervening logout could result in the prior user's session
48+
being co-opted by the subsequent user. The middleware now logs the user out on
49+
a failed login attempt.

docs/releases/1.5.9.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,12 @@ if a file with the uploaded name already exists.
3838
underscore plus a random 7 character alphanumeric string (e.g. ``"_x3a1gho"``),
3939
rather than iterating through an underscore followed by a number (e.g. ``"_1"``,
4040
``"_2"``, etc.).
41+
42+
``RemoteUserMiddleware`` session hijacking
43+
==========================================
44+
45+
When using the :class:`~django.contrib.auth.middleware.RemoteUserMiddleware`
46+
and the ``RemoteUserBackend``, a change to the ``REMOTE_USER`` header between
47+
requests without an intervening logout could result in the prior user's session
48+
being co-opted by the subsequent user. The middleware now logs the user out on
49+
a failed login attempt.

docs/releases/1.6.6.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ underscore plus a random 7 character alphanumeric string (e.g. ``"_x3a1gho"``),
3939
rather than iterating through an underscore followed by a number (e.g. ``"_1"``,
4040
``"_2"``, etc.).
4141

42+
``RemoteUserMiddleware`` session hijacking
43+
==========================================
44+
45+
When using the :class:`~django.contrib.auth.middleware.RemoteUserMiddleware`
46+
and the ``RemoteUserBackend``, a change to the ``REMOTE_USER`` header between
47+
requests without an intervening logout could result in the prior user's session
48+
being co-opted by the subsequent user. The middleware now logs the user out on
49+
a failed login attempt.
50+
4251
Bugfixes
4352
========
4453

0 commit comments

Comments
 (0)