From 9e462f810194800af30ea19a6fb8ac5697d839b4 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Wed, 27 Mar 2013 11:23:59 -0500 Subject: [PATCH] Fixed #20078: don't allow filtering on password in the user admin. --- django/contrib/auth/admin.py | 6 ++++++ django/contrib/auth/tests/urls_admin.py | 18 ++++++++++++++++++ django/contrib/auth/tests/views.py | 15 +++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 django/contrib/auth/tests/urls_admin.py diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py index bff8041e05e..409078fa029 100644 --- a/django/contrib/auth/admin.py +++ b/django/contrib/auth/admin.py @@ -83,6 +83,12 @@ class UserAdmin(admin.ModelAdmin): self.admin_site.admin_view(self.user_change_password)) ) + super(UserAdmin, self).get_urls() + def lookup_allowed(self, lookup, value): + # See #20078: we don't want to allow any lookups involving passwords. + if lookup.startswith('password'): + return False + return super(UserAdmin, self).lookup_allowed(lookup, value) + @sensitive_post_parameters() @csrf_protect_m @transaction.atomic diff --git a/django/contrib/auth/tests/urls_admin.py b/django/contrib/auth/tests/urls_admin.py new file mode 100644 index 00000000000..14a38e40d38 --- /dev/null +++ b/django/contrib/auth/tests/urls_admin.py @@ -0,0 +1,18 @@ +""" +Test URLs for auth admins. +""" + +from django.conf.urls import patterns, include +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin, GroupAdmin +from django.contrib.auth.models import User, Group +from django.contrib.auth.urls import urlpatterns + +# Create a silo'd admin site for just the user/group admins. +site = admin.AdminSite(name='auth_test_admin') +site.register(User, UserAdmin) +site.register(Group, GroupAdmin) + +urlpatterns = urlpatterns + patterns('', + (r'^admin/', include(site.urls)), +) diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py index ee1b18d0384..7cbf72327e3 100644 --- a/django/contrib/auth/tests/views.py +++ b/django/contrib/auth/tests/views.py @@ -528,3 +528,18 @@ class LogoutTest(AuthViewsTestCase): self.assertTrue(good_url in response.url, "%s should be allowed" % good_url) self.confirm_logged_out() + +@skipIfCustomUser +class ChangelistTests(AuthViewsTestCase): + urls = 'django.contrib.auth.tests.urls_admin' + + # #20078 - users shouldn't be allowed to guess password hashes via + # repeated password__startswith queries. + def test_changelist_disallows_password_lookups(self): + # Make me a superuser before loging in. + User.objects.filter(username='testclient').update(is_staff=True, is_superuser=True) + self.login() + + # A lookup that tries to filter on password isn't OK + with self.assertRaises(SuspiciousOperation): + response = self.client.get('/admin/auth/user/?password__startswith=sha1$')