1
0
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:
Tim Graham
2014-12-11 08:31:03 -05:00
parent 818e59a3f0
commit bcfb47780c
5 changed files with 63 additions and 5 deletions

View File

@@ -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):