A RetroSearch Logo

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

Search Query:

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

[1.7.x] Fixed DoS possibility in ModelMultipleChoiceField. · django/django@bcfb477 · GitHub

File tree Expand file treeCollapse file tree 5 files changed

+63

-5

lines changed

Filter options

Expand file treeCollapse file tree 5 files changed

+63

-5

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

@@ -1221,8 +1221,7 @@ def __init__(self, queryset, cache_choices=False, required=True,

1221 1221

def to_python(self, value):

1222 1222

if not value:

1223 1223

return []

1224 -

to_py = super(ModelMultipleChoiceField, self).to_python

1225 -

return [to_py(val) for val in value]

1224 +

return list(self._check_values(value))

1226 1225 1227 1226

def clean(self, value):

1228 1227

if self.required and not value:

@@ -1231,7 +1230,29 @@ def clean(self, value):

1231 1230

return self.queryset.none()

1232 1231

if not isinstance(value, (list, tuple)):

1233 1232

raise ValidationError(self.error_messages['list'], code='list')

1233 +

qs = self._check_values(value)

1234 +

# Since this overrides the inherited ModelChoiceField.clean

1235 +

# we run custom validators here

1236 +

self.run_validators(value)

1237 +

return qs

1238 + 1239 +

def _check_values(self, value):

1240 +

"""

1241 +

Given a list of possible PK values, returns a QuerySet of the

1242 +

corresponding objects. Raises a ValidationError if a given value is

1243 +

invalid (not a valid PK, not in the queryset, etc.)

1244 +

"""

1234 1245

key = self.to_field_name or 'pk'

1246 +

# deduplicate given values to avoid creating many querysets or

1247 +

# requiring the database backend deduplicate efficiently.

1248 +

try:

1249 +

value = frozenset(value)

1250 +

except TypeError:

1251 +

# list of lists isn't hashable, for example

1252 +

raise ValidationError(

1253 +

self.error_messages['list'],

1254 +

code='list',

1255 +

)

1235 1256

for pk in value:

1236 1257

try:

1237 1258

self.queryset.filter(**{key: pk})

@@ -1250,9 +1271,6 @@ def clean(self, value):

1250 1271

code='invalid_choice',

1251 1272

params={'value': val},

1252 1273

)

1253 -

# Since this overrides the inherited ModelChoiceField.clean

1254 -

# we run custom validators here

1255 -

self.run_validators(value)

1256 1274

return qs

1257 1275 1258 1276

def prepare_value(self, value):

Original file line number Diff line number Diff line change

@@ -58,3 +58,12 @@ Note, however, that this view has always carried a warning that it is not

58 58

hardened for production use and should be used only as a development aid. Now

59 59

may be a good time to audit your project and serve your files in production

60 60

using a real front-end web server if you are not doing so.

61 + 62 +

Database denial-of-service with ``ModelMultipleChoiceField``

63 +

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

64 + 65 +

Given a form that uses ``ModelMultipleChoiceField`` and

66 +

``show_hidden_initial=True`` (not a documented API), it was possible for a user

67 +

to cause an unreasonable number of SQL queries by submitting duplicate values

68 +

for the field's data. The validation logic in ``ModelMultipleChoiceField`` now

69 +

deduplicates submitted values to address this issue.

Original file line number Diff line number Diff line change

@@ -59,6 +59,15 @@ hardened for production use and should be used only as a development aid. Now

59 59

may be a good time to audit your project and serve your files in production

60 60

using a real front-end web server if you are not doing so.

61 61 62 +

Database denial-of-service with ``ModelMultipleChoiceField``

63 +

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

64 + 65 +

Given a form that uses ``ModelMultipleChoiceField`` and

66 +

``show_hidden_initial=True`` (not a documented API), it was possible for a user

67 +

to cause an unreasonable number of SQL queries by submitting duplicate values

68 +

for the field's data. The validation logic in ``ModelMultipleChoiceField`` now

69 +

deduplicates submitted values to address this issue.

70 + 62 71

Bugfixes

63 72

========

64 73 Original file line number Diff line number Diff line change

@@ -134,6 +134,7 @@ dbshell

134 134

de

135 135

deconstruct

136 136

deconstructing

137 +

deduplicates

137 138

deepcopy

138 139

deserialization

139 140

deserialize

Original file line number Diff line number Diff line change

@@ -1573,6 +1573,27 @@ class WriterForm(forms.Form):

1573 1573

self.assertTrue(form.is_valid())

1574 1574

self.assertTrue(form.has_changed())

1575 1575 1576 +

def test_show_hidden_initial_changed_queries_efficiently(self):

1577 +

class WriterForm(forms.Form):

1578 +

persons = forms.ModelMultipleChoiceField(

1579 +

show_hidden_initial=True, queryset=Writer.objects.all())

1580 + 1581 +

writers = (Writer.objects.create(name=str(x)) for x in range(0, 50))

1582 +

writer_pks = tuple(x.pk for x in writers)

1583 +

form = WriterForm(data={'initial-persons': writer_pks})

1584 +

with self.assertNumQueries(1):

1585 +

self.assertTrue(form.has_changed())

1586 + 1587 +

def test_clean_does_deduplicate_values(self):

1588 +

class WriterForm(forms.Form):

1589 +

persons = forms.ModelMultipleChoiceField(queryset=Writer.objects.all())

1590 + 1591 +

person1 = Writer.objects.create(name="Person 1")

1592 +

form = WriterForm(data={})

1593 +

queryset = form.fields['persons'].clean([str(person1.pk)] * 50)

1594 +

sql, params = queryset.query.sql_with_params()

1595 +

self.assertEqual(len(params), 1)

1596 + 1576 1597 1577 1598

class ModelOneToOneFieldTests(TestCase):

1578 1599

def test_modelform_onetoonefield(self):

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