mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
[1.7.x] Fixed DoS possibility in ModelMultipleChoiceField.
This is a security fix. Disclosure following shortly. Thanks Keryn Knight for the report and initial patch.
This commit is contained in:
@@ -1221,8 +1221,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||
def to_python(self, value):
|
||||
if not value:
|
||||
return []
|
||||
to_py = super(ModelMultipleChoiceField, self).to_python
|
||||
return [to_py(val) for val in value]
|
||||
return list(self._check_values(value))
|
||||
|
||||
def clean(self, value):
|
||||
if self.required and not value:
|
||||
@@ -1231,7 +1230,29 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||
return self.queryset.none()
|
||||
if not isinstance(value, (list, tuple)):
|
||||
raise ValidationError(self.error_messages['list'], code='list')
|
||||
qs = self._check_values(value)
|
||||
# Since this overrides the inherited ModelChoiceField.clean
|
||||
# we run custom validators here
|
||||
self.run_validators(value)
|
||||
return qs
|
||||
|
||||
def _check_values(self, value):
|
||||
"""
|
||||
Given a list of possible PK values, returns a QuerySet of the
|
||||
corresponding objects. Raises a ValidationError if a given value is
|
||||
invalid (not a valid PK, not in the queryset, etc.)
|
||||
"""
|
||||
key = self.to_field_name or 'pk'
|
||||
# deduplicate given values to avoid creating many querysets or
|
||||
# requiring the database backend deduplicate efficiently.
|
||||
try:
|
||||
value = frozenset(value)
|
||||
except TypeError:
|
||||
# list of lists isn't hashable, for example
|
||||
raise ValidationError(
|
||||
self.error_messages['list'],
|
||||
code='list',
|
||||
)
|
||||
for pk in value:
|
||||
try:
|
||||
self.queryset.filter(**{key: pk})
|
||||
@@ -1250,9 +1271,6 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||
code='invalid_choice',
|
||||
params={'value': val},
|
||||
)
|
||||
# Since this overrides the inherited ModelChoiceField.clean
|
||||
# we run custom validators here
|
||||
self.run_validators(value)
|
||||
return qs
|
||||
|
||||
def prepare_value(self, value):
|
||||
|
||||
Reference in New Issue
Block a user