A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/027bd348642007617518379f8b02546abacaa6e0 below:

[1.4.x] Prevented data leakage in contrib.admin via query string mani… · django/django@027bd34 · GitHub

File tree Expand file treeCollapse file tree 5 files changed

+61

-5

lines changed

Filter options

Expand file treeCollapse file tree 5 files changed

+61

-5

lines changed Original file line number Diff line number Diff line change

@@ -0,0 +1,6 @@

1 +

from django.core.exceptions import SuspiciousOperation

2 + 3 + 4 +

class DisallowedModelAdminToField(SuspiciousOperation):

5 +

"""Invalid to_field was passed to admin view via URL query string"""

6 +

pass

Original file line number Diff line number Diff line change

@@ -269,6 +269,24 @@ def lookup_allowed(self, lookup, value):

269 269

clean_lookup = LOOKUP_SEP.join(parts)

270 270

return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

271 271 272 +

def to_field_allowed(self, request, to_field):

273 +

opts = self.model._meta

274 + 275 +

try:

276 +

field = opts.get_field(to_field)

277 +

except FieldDoesNotExist:

278 +

return False

279 + 280 +

# Make sure at least one of the models registered for this site

281 +

# references this field.

282 +

registered_models = self.admin_site._registry

283 +

for related_object in opts.get_all_related_objects():

284 +

if (related_object.model in registered_models and

285 +

field == related_object.field.rel.get_related_field()):

286 +

return True

287 + 288 +

return False

289 + 272 290

def has_add_permission(self, request):

273 291

"""

274 292

Returns True if the given request has permission to add an object.

Original file line number Diff line number Diff line change

@@ -10,6 +10,7 @@

10 10

from django.utils.http import urlencode

11 11 12 12

from django.contrib.admin import FieldListFilter

13 +

from django.contrib.admin.exceptions import DisallowedModelAdminToField

13 14

from django.contrib.admin.options import IncorrectLookupParameters

14 15

from django.contrib.admin.util import (quote, get_fields_from_path,

15 16

lookup_needs_distinct, prepare_lookup_value)

@@ -56,7 +57,10 @@ def __init__(self, request, model, list_display, list_display_links,

56 57

self.page_num = 0

57 58

self.show_all = ALL_VAR in request.GET

58 59

self.is_popup = IS_POPUP_VAR in request.GET

59 -

self.to_field = request.GET.get(TO_FIELD_VAR)

60 +

to_field = request.GET.get(TO_FIELD_VAR)

61 +

if to_field and not model_admin.to_field_allowed(request, to_field):

62 +

raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)

63 +

self.to_field = to_field

60 64

self.params = dict(request.GET.items())

61 65

if PAGE_VAR in self.params:

62 66

del self.params[PAGE_VAR]

Original file line number Diff line number Diff line change

@@ -47,3 +47,18 @@ and the ``RemoteUserBackend``, a change to the ``REMOTE_USER`` header between

47 47

requests without an intervening logout could result in the prior user's session

48 48

being co-opted by the subsequent user. The middleware now logs the user out on

49 49

a failed login attempt.

50 + 51 +

Data leakage via query string manipulation in ``contrib.admin``

52 +

===============================================================

53 + 54 +

In older versions of Django it was possible to reveal any field's data by

55 +

modifying the "popup" and "to_field" parameters of the query string on an admin

56 +

change form page. For example, requesting a URL like

57 +

``/admin/auth/user/?pop=1&t=password`` and viewing the page's HTML allowed

58 +

viewing the password hash of each user. While the admin requires users to have

59 +

permissions to view the change form pages in the first place, this could leak

60 +

data if you rely on users having access to view only certain fields on a model.

61 + 62 +

To address the issue, an exception will now be raised if a ``to_field`` value

63 +

that isn't a related field to a model that has been registered with the admin

64 +

is specified.

Original file line number Diff line number Diff line change

@@ -13,11 +13,12 @@

13 13

from django.core.urlresolvers import reverse

14 14

# Register auth models with the admin.

15 15

from django.contrib import admin

16 +

from django.contrib.admin.exceptions import DisallowedModelAdminToField

16 17

from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME

17 18

from django.contrib.admin.models import LogEntry, DELETION

18 19

from django.contrib.admin.sites import LOGIN_FORM_KEY

19 20

from django.contrib.admin.util import quote

20 -

from django.contrib.admin.views.main import IS_POPUP_VAR

21 +

from django.contrib.admin.views.main import IS_POPUP_VAR, TO_FIELD_VAR

21 22

from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase

22 23

from django.contrib.auth import REDIRECT_FIELD_NAME

23 24

from django.contrib.auth.models import Group, User, Permission, UNUSABLE_PASSWORD

@@ -572,6 +573,19 @@ def test_disallowed_filtering(self):

572 573

response = self.client.get("/test_admin/admin/admin_views/workhour/?employee__person_ptr__exact=%d" % e1.pk)

573 574

self.assertEqual(response.status_code, 200)

574 575 576 +

def test_disallowed_to_field(self):

577 +

with self.assertRaises(DisallowedModelAdminToField):

578 +

response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'missing_field'})

579 + 580 +

# Specifying a field that is not refered by any other model registered

581 +

# to this admin site should raise an exception.

582 +

with self.assertRaises(DisallowedModelAdminToField):

583 +

response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'name'})

584 + 585 +

# Specifying a field referenced by another model should be allowed.

586 +

response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'id'})

587 +

self.assertEqual(response.status_code, 200)

588 + 575 589

def test_allowed_filtering_15103(self):

576 590

"""

577 591

Regressions test for ticket 15103 - filtering on fields defined in a

@@ -2061,10 +2075,9 @@ def test_with_fk_to_field(self):

2061 2075

"""Ensure that the to_field GET parameter is preserved when a search

2062 2076

is performed. Refs #10918.

2063 2077

"""

2064 -

from django.contrib.admin.views.main import TO_FIELD_VAR

2065 -

response = self.client.get('/test_admin/admin/auth/user/?q=joe&%s=username' % TO_FIELD_VAR)

2078 +

response = self.client.get('/test_admin/admin/auth/user/?q=joe&%s=id' % TO_FIELD_VAR)

2066 2079

self.assertContains(response, "\n1 user\n")

2067 -

self.assertContains(response, '<input type="hidden" name="t" value="username"/>', html=True)

2080 +

self.assertContains(response, '<input type="hidden" name="%s" value="id"/>' % TO_FIELD_VAR, html=True)

2068 2081 2069 2082

def test_exact_matches(self):

2070 2083

response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar')

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4