Skip to content

Commit bacf8cf

Browse files
committed
Guard against malicious string inputs for numbers. Closes #1903.
1 parent 3dfb6b0 commit bacf8cf

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

rest_framework/fields.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,9 @@ class IntegerField(Field):
545545
'invalid': _('A valid integer is required.'),
546546
'max_value': _('Ensure this value is less than or equal to {max_value}.'),
547547
'min_value': _('Ensure this value is greater than or equal to {min_value}.'),
548+
'max_string_length': _('String value too large')
548549
}
550+
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
549551

550552
def __init__(self, **kwargs):
551553
max_value = kwargs.pop('max_value', None)
@@ -559,8 +561,11 @@ def __init__(self, **kwargs):
559561
self.validators.append(MinValueValidator(min_value, message=message))
560562

561563
def to_internal_value(self, data):
564+
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
565+
self.fail('max_string_length')
566+
562567
try:
563-
data = int(six.text_type(data))
568+
data = int(data)
564569
except (ValueError, TypeError):
565570
self.fail('invalid')
566571
return data
@@ -574,7 +579,9 @@ class FloatField(Field):
574579
'invalid': _("A valid number is required."),
575580
'max_value': _('Ensure this value is less than or equal to {max_value}.'),
576581
'min_value': _('Ensure this value is greater than or equal to {min_value}.'),
582+
'max_string_length': _('String value too large')
577583
}
584+
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
578585

579586
def __init__(self, **kwargs):
580587
max_value = kwargs.pop('max_value', None)
@@ -587,9 +594,12 @@ def __init__(self, **kwargs):
587594
message = self.error_messages['min_value'].format(min_value=min_value)
588595
self.validators.append(MinValueValidator(min_value, message=message))
589596

590-
def to_internal_value(self, value):
597+
def to_internal_value(self, data):
598+
if isinstance(data, six.text_type) and len(data) > self.MAX_STRING_LENGTH:
599+
self.fail('max_string_length')
600+
591601
try:
592-
return float(value)
602+
return float(data)
593603
except (TypeError, ValueError):
594604
self.fail('invalid')
595605

@@ -604,8 +614,10 @@ class DecimalField(Field):
604614
'min_value': _('Ensure this value is greater than or equal to {min_value}.'),
605615
'max_digits': _('Ensure that there are no more than {max_digits} digits in total.'),
606616
'max_decimal_places': _('Ensure that there are no more than {max_decimal_places} decimal places.'),
607-
'max_whole_digits': _('Ensure that there are no more than {max_whole_digits} digits before the decimal point.')
617+
'max_whole_digits': _('Ensure that there are no more than {max_whole_digits} digits before the decimal point.'),
618+
'max_string_length': _('String value too large')
608619
}
620+
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
609621

610622
coerce_to_string = api_settings.COERCE_DECIMAL_TO_STRING
611623

@@ -621,16 +633,19 @@ def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=
621633
message = self.error_messages['min_value'].format(min_value=min_value)
622634
self.validators.append(MinValueValidator(min_value, message=message))
623635

624-
def to_internal_value(self, value):
636+
def to_internal_value(self, data):
625637
"""
626638
Validates that the input is a decimal number. Returns a Decimal
627639
instance. Returns None for empty values. Ensures that there are no more
628640
than max_digits in the number, and no more than decimal_places digits
629641
after the decimal point.
630642
"""
631-
value = smart_text(value).strip()
643+
data = smart_text(data).strip()
644+
if len(data) > self.MAX_STRING_LENGTH:
645+
self.fail('max_string_length')
646+
632647
try:
633-
value = decimal.Decimal(value)
648+
value = decimal.Decimal(data)
634649
except decimal.DecimalException:
635650
self.fail('invalid')
636651

0 commit comments

Comments
 (0)