Fixed CVE-2021-33571 -- Prevented leading zeros in IPv4 addresses.
validate_ipv4_address() was affected only on Python < 3.9.5, see [1]. URLValidator() uses a regular expressions and it was affected on all Python versions. [1] https://bugs.python.org/issue36384
This commit is contained in:
parent
46572de2e9
commit
e1d787f1b3
|
@ -66,7 +66,7 @@ class URLValidator(RegexValidator):
|
||||||
ul = '\u00a1-\uffff' # Unicode letters range (must not be a raw string).
|
ul = '\u00a1-\uffff' # Unicode letters range (must not be a raw string).
|
||||||
|
|
||||||
# IP patterns
|
# IP patterns
|
||||||
ipv4_re = r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
|
ipv4_re = r'(?:0|25[0-5]|2[0-4]\d|1\d?\d?|[1-9]\d?)(?:\.(?:0|25[0-5]|2[0-4]\d|1\d?\d?|[1-9]\d?)){3}'
|
||||||
ipv6_re = r'\[[0-9a-f:.]+\]' # (simple regex, validated later)
|
ipv6_re = r'\[[0-9a-f:.]+\]' # (simple regex, validated later)
|
||||||
|
|
||||||
# Host patterns
|
# Host patterns
|
||||||
|
@ -276,6 +276,19 @@ def validate_ipv4_address(value):
|
||||||
ipaddress.IPv4Address(value)
|
ipaddress.IPv4Address(value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError(_('Enter a valid IPv4 address.'), code='invalid', params={'value': value})
|
raise ValidationError(_('Enter a valid IPv4 address.'), code='invalid', params={'value': value})
|
||||||
|
else:
|
||||||
|
# Leading zeros are forbidden to avoid ambiguity with the octal
|
||||||
|
# notation. This restriction is included in Python 3.9.5+.
|
||||||
|
# TODO: Remove when dropping support for PY39.
|
||||||
|
if any(
|
||||||
|
octet != '0' and octet[0] == '0'
|
||||||
|
for octet in value.split('.')
|
||||||
|
):
|
||||||
|
raise ValidationError(
|
||||||
|
_('Enter a valid IPv4 address.'),
|
||||||
|
code='invalid',
|
||||||
|
params={'value': value},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_ipv6_address(value):
|
def validate_ipv6_address(value):
|
||||||
|
|
|
@ -17,3 +17,16 @@ the existence but also the file contents would have been exposed.
|
||||||
|
|
||||||
As a mitigation, path sanitation is now applied and only files within the
|
As a mitigation, path sanitation is now applied and only files within the
|
||||||
template root directories can be loaded.
|
template root directories can be loaded.
|
||||||
|
|
||||||
|
CVE-2021-33571: Possible indeterminate SSRF, RFI, and LFI attacks since validators accepted leading zeros in IPv4 addresses
|
||||||
|
===========================================================================================================================
|
||||||
|
|
||||||
|
:class:`~django.core.validators.URLValidator`,
|
||||||
|
:func:`~django.core.validators.validate_ipv4_address`, and
|
||||||
|
:func:`~django.core.validators.validate_ipv46_address` didn't prohibit leading
|
||||||
|
zeros in octal literals. If you used such values you could suffer from
|
||||||
|
indeterminate SSRF, RFI, and LFI attacks.
|
||||||
|
|
||||||
|
:func:`~django.core.validators.validate_ipv4_address` and
|
||||||
|
:func:`~django.core.validators.validate_ipv46_address` validators were not
|
||||||
|
affected on Python 3.9.5+.
|
||||||
|
|
|
@ -17,3 +17,16 @@ the existence but also the file contents would have been exposed.
|
||||||
|
|
||||||
As a mitigation, path sanitation is now applied and only files within the
|
As a mitigation, path sanitation is now applied and only files within the
|
||||||
template root directories can be loaded.
|
template root directories can be loaded.
|
||||||
|
|
||||||
|
CVE-2021-33571: Possible indeterminate SSRF, RFI, and LFI attacks since validators accepted leading zeros in IPv4 addresses
|
||||||
|
===========================================================================================================================
|
||||||
|
|
||||||
|
:class:`~django.core.validators.URLValidator`,
|
||||||
|
:func:`~django.core.validators.validate_ipv4_address`, and
|
||||||
|
:func:`~django.core.validators.validate_ipv46_address` didn't prohibit leading
|
||||||
|
zeros in octal literals. If you used such values you could suffer from
|
||||||
|
indeterminate SSRF, RFI, and LFI attacks.
|
||||||
|
|
||||||
|
:func:`~django.core.validators.validate_ipv4_address` and
|
||||||
|
:func:`~django.core.validators.validate_ipv46_address` validators were not
|
||||||
|
affected on Python 3.9.5+.
|
||||||
|
|
|
@ -18,6 +18,19 @@ the existence but also the file contents would have been exposed.
|
||||||
As a mitigation, path sanitation is now applied and only files within the
|
As a mitigation, path sanitation is now applied and only files within the
|
||||||
template root directories can be loaded.
|
template root directories can be loaded.
|
||||||
|
|
||||||
|
CVE-2021-33571: Possible indeterminate SSRF, RFI, and LFI attacks since validators accepted leading zeros in IPv4 addresses
|
||||||
|
===========================================================================================================================
|
||||||
|
|
||||||
|
:class:`~django.core.validators.URLValidator`,
|
||||||
|
:func:`~django.core.validators.validate_ipv4_address`, and
|
||||||
|
:func:`~django.core.validators.validate_ipv46_address` didn't prohibit leading
|
||||||
|
zeros in octal literals. If you used such values you could suffer from
|
||||||
|
indeterminate SSRF, RFI, and LFI attacks.
|
||||||
|
|
||||||
|
:func:`~django.core.validators.validate_ipv4_address` and
|
||||||
|
:func:`~django.core.validators.validate_ipv46_address` validators were not
|
||||||
|
affected on Python 3.9.5+.
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,14 @@ http://1.1.1.1.1
|
||||||
http://123.123.123
|
http://123.123.123
|
||||||
http://3628126748
|
http://3628126748
|
||||||
http://123
|
http://123
|
||||||
|
http://000.000.000.000
|
||||||
|
http://016.016.016.016
|
||||||
|
http://192.168.000.001
|
||||||
|
http://01.2.3.4
|
||||||
|
http://01.2.3.4
|
||||||
|
http://1.02.3.4
|
||||||
|
http://1.2.03.4
|
||||||
|
http://1.2.3.04
|
||||||
http://.www.foo.bar/
|
http://.www.foo.bar/
|
||||||
http://.www.foo.bar./
|
http://.www.foo.bar./
|
||||||
http://[::1:2::3]:8080/
|
http://[::1:2::3]:8080/
|
||||||
|
|
|
@ -136,6 +136,16 @@ TEST_DATA = [
|
||||||
(validate_ipv4_address, '1.1.1.1\n', ValidationError),
|
(validate_ipv4_address, '1.1.1.1\n', ValidationError),
|
||||||
(validate_ipv4_address, '٧.2٥.3٣.243', ValidationError),
|
(validate_ipv4_address, '٧.2٥.3٣.243', ValidationError),
|
||||||
|
|
||||||
|
# Leading zeros are forbidden to avoid ambiguity with the octal notation.
|
||||||
|
(validate_ipv4_address, '000.000.000.000', ValidationError),
|
||||||
|
(validate_ipv4_address, '016.016.016.016', ValidationError),
|
||||||
|
(validate_ipv4_address, '192.168.000.001', ValidationError),
|
||||||
|
(validate_ipv4_address, '01.2.3.4', ValidationError),
|
||||||
|
(validate_ipv4_address, '01.2.3.4', ValidationError),
|
||||||
|
(validate_ipv4_address, '1.02.3.4', ValidationError),
|
||||||
|
(validate_ipv4_address, '1.2.03.4', ValidationError),
|
||||||
|
(validate_ipv4_address, '1.2.3.04', ValidationError),
|
||||||
|
|
||||||
# validate_ipv6_address uses django.utils.ipv6, which
|
# validate_ipv6_address uses django.utils.ipv6, which
|
||||||
# is tested in much greater detail in its own testcase
|
# is tested in much greater detail in its own testcase
|
||||||
(validate_ipv6_address, 'fe80::1', None),
|
(validate_ipv6_address, 'fe80::1', None),
|
||||||
|
@ -161,6 +171,16 @@ TEST_DATA = [
|
||||||
(validate_ipv46_address, '::zzz', ValidationError),
|
(validate_ipv46_address, '::zzz', ValidationError),
|
||||||
(validate_ipv46_address, '12345::', ValidationError),
|
(validate_ipv46_address, '12345::', ValidationError),
|
||||||
|
|
||||||
|
# Leading zeros are forbidden to avoid ambiguity with the octal notation.
|
||||||
|
(validate_ipv46_address, '000.000.000.000', ValidationError),
|
||||||
|
(validate_ipv46_address, '016.016.016.016', ValidationError),
|
||||||
|
(validate_ipv46_address, '192.168.000.001', ValidationError),
|
||||||
|
(validate_ipv46_address, '01.2.3.4', ValidationError),
|
||||||
|
(validate_ipv46_address, '01.2.3.4', ValidationError),
|
||||||
|
(validate_ipv46_address, '1.02.3.4', ValidationError),
|
||||||
|
(validate_ipv46_address, '1.2.03.4', ValidationError),
|
||||||
|
(validate_ipv46_address, '1.2.3.04', ValidationError),
|
||||||
|
|
||||||
(validate_comma_separated_integer_list, '1', None),
|
(validate_comma_separated_integer_list, '1', None),
|
||||||
(validate_comma_separated_integer_list, '12', None),
|
(validate_comma_separated_integer_list, '12', None),
|
||||||
(validate_comma_separated_integer_list, '1,2', None),
|
(validate_comma_separated_integer_list, '1,2', None),
|
||||||
|
|
|
@ -71,6 +71,12 @@ http://0.0.0.0/
|
||||||
http://255.255.255.255
|
http://255.255.255.255
|
||||||
http://224.0.0.0
|
http://224.0.0.0
|
||||||
http://224.1.1.1
|
http://224.1.1.1
|
||||||
|
http://111.112.113.114/
|
||||||
|
http://88.88.88.88/
|
||||||
|
http://11.12.13.14/
|
||||||
|
http://10.20.30.40/
|
||||||
|
http://1.2.3.4/
|
||||||
|
http://127.0.01.09.home.lan
|
||||||
http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com
|
http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com
|
||||||
http://example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com
|
http://example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com
|
||||||
http://example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
http://example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
Loading…
Reference in New Issue