From 174d8db57caf56e845aee54c02b57c14b777f892 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Thu, 24 Feb 2011 13:34:51 +0000 Subject: [PATCH] Prevented non-admin users from accessing the admin redirect shortcut. If the admin shortcut view (e.g. /admin/r///) is publically-accessible, and if a public users can guess a content-type ID (which isn't hard given that they're sequential), then the redirect view could possibly leak data by redirecting to pages a user shouldn't "know about." So the redirect view needs the same protection as the rest of the admin site. Thanks to Jason Royes for pointing this out. git-svn-id: http://code.djangoproject.com/svn/django/trunk@15639 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/sites.py | 3 ++- tests/regressiontests/admin_views/tests.py | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 4585627a0b..4b6e3cad87 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -3,6 +3,7 @@ from django import http, template from django.contrib.admin import ModelAdmin, actions from django.contrib.admin.forms import AdminAuthenticationForm, ERROR_MESSAGE from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate, login +from django.contrib.contenttypes import views as contenttype_views from django.views.decorators.csrf import csrf_protect from django.db.models.base import ModelBase from django.core.exceptions import ImproperlyConfigured @@ -231,7 +232,7 @@ class AdminSite(object): wrap(self.i18n_javascript, cacheable=True), name='jsi18n'), url(r'^r/(?P\d+)/(?P.+)/$', - 'django.views.defaults.shortcut'), + wrap(contenttype_views.shortcut)), url(r'^(?P\w+)/$', wrap(self.app_index), name='app_list') diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index aa8bf07380..7782f9eab7 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -1143,7 +1143,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): self.assertContains(response, should_contain) -class SecureViewTest(TestCase): +class SecureViewTests(TestCase): fixtures = ['admin-views-users.xml'] def setUp(self): @@ -1281,6 +1281,25 @@ class SecureViewTest(TestCase): # make sure the view removes test cookie self.assertEqual(self.client.session.test_cookie_worked(), False) + def test_shortcut_view_only_available_to_staff(self): + """ + Only admin users should be able to use the admin shortcut view. + """ + user_ctype = ContentType.objects.get_for_model(User) + user = User.objects.get(username='super') + shortcut_url = "/test_admin/admin/r/%s/%s/" % (user_ctype.pk, user.pk) + + # Not logged in: we should see the login page. + response = self.client.get(shortcut_url, follow=False) + self.assertTemplateUsed(response, 'admin/login.html') + + # Logged in? Redirect. + self.client.login(username='super', password='secret') + response = self.client.get(shortcut_url, follow=False) + # Can't use self.assertRedirects() because User.get_absolute_url() is silly. + self.assertEqual(response.status_code, 302) + self.assertEqual(response['Location'], 'http://example.com/users/super/') + class AdminViewUnicodeTest(TestCase): fixtures = ['admin-views-unicode.xml'] @@ -2872,3 +2891,4 @@ class DateHierarchyTests(TestCase): self.assert_non_localized_year(response, 2000) self.assert_non_localized_year(response, 2003) self.assert_non_localized_year(response, 2005) +