diff options
| author | Tom Christie | 2014-10-31 15:40:08 +0000 | 
|---|---|---|
| committer | Tom Christie | 2014-10-31 15:41:00 +0000 | 
| commit | bacf8cfa9d9331d0876e7ad7adccdabc5f4833a5 (patch) | |
| tree | 40880fd5f27bfaa1ecf1fb3d66ec94b8cbd76311 /rest_framework/fields.py | |
| parent | 3dfb6b0e509a7fed88dd8f84c93a89d5fcf2e262 (diff) | |
| download | django-rest-framework-bacf8cfa9d9331d0876e7ad7adccdabc5f4833a5.tar.bz2 | |
Guard against malicious string inputs for numbers. Closes #1903.
Diffstat (limited to 'rest_framework/fields.py')
| -rw-r--r-- | rest_framework/fields.py | 29 | 
1 files changed, 22 insertions, 7 deletions
| diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 82b7eb37..d5dccd72 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -545,7 +545,9 @@ class IntegerField(Field):          'invalid': _('A valid integer is required.'),          'max_value': _('Ensure this value is less than or equal to {max_value}.'),          'min_value': _('Ensure this value is greater than or equal to {min_value}.'), +        'max_string_length': _('String value too large')      } +    MAX_STRING_LENGTH = 1000  # Guard against malicious string inputs.      def __init__(self, **kwargs):          max_value = kwargs.pop('max_value', None) @@ -559,8 +561,11 @@ class IntegerField(Field):              self.validators.append(MinValueValidator(min_value, message=message))      def to_internal_value(self, data): +        if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH: +            self.fail('max_string_length') +          try: -            data = int(six.text_type(data)) +            data = int(data)          except (ValueError, TypeError):              self.fail('invalid')          return data @@ -574,7 +579,9 @@ class FloatField(Field):          'invalid': _("A valid number is required."),          'max_value': _('Ensure this value is less than or equal to {max_value}.'),          'min_value': _('Ensure this value is greater than or equal to {min_value}.'), +        'max_string_length': _('String value too large')      } +    MAX_STRING_LENGTH = 1000  # Guard against malicious string inputs.      def __init__(self, **kwargs):          max_value = kwargs.pop('max_value', None) @@ -587,9 +594,12 @@ class FloatField(Field):              message = self.error_messages['min_value'].format(min_value=min_value)              self.validators.append(MinValueValidator(min_value, message=message)) -    def to_internal_value(self, value): +    def to_internal_value(self, data): +        if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH: +            self.fail('max_string_length') +          try: -            return float(value) +            return float(data)          except (TypeError, ValueError):              self.fail('invalid') @@ -604,8 +614,10 @@ class DecimalField(Field):          'min_value': _('Ensure this value is greater than or equal to {min_value}.'),          'max_digits': _('Ensure that there are no more than {max_digits} digits in total.'),          'max_decimal_places': _('Ensure that there are no more than {max_decimal_places} decimal places.'), -        'max_whole_digits': _('Ensure that there are no more than {max_whole_digits} digits before the decimal point.') +        'max_whole_digits': _('Ensure that there are no more than {max_whole_digits} digits before the decimal point.'), +        'max_string_length': _('String value too large')      } +    MAX_STRING_LENGTH = 1000  # Guard against malicious string inputs.      coerce_to_string = api_settings.COERCE_DECIMAL_TO_STRING @@ -621,16 +633,19 @@ class DecimalField(Field):              message = self.error_messages['min_value'].format(min_value=min_value)              self.validators.append(MinValueValidator(min_value, message=message)) -    def to_internal_value(self, value): +    def to_internal_value(self, data):          """          Validates that the input is a decimal number. Returns a Decimal          instance. Returns None for empty values. Ensures that there are no more          than max_digits in the number, and no more than decimal_places digits          after the decimal point.          """ -        value = smart_text(value).strip() +        data = smart_text(data).strip() +        if len(data) > self.MAX_STRING_LENGTH: +            self.fail('max_string_length') +          try: -            value = decimal.Decimal(value) +            value = decimal.Decimal(data)          except decimal.DecimalException:              self.fail('invalid') | 
