summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2021-05-25 11:57:59 +0200
committerCarlton Gibson <carlton.gibson@noumenal.es>2021-06-02 10:26:22 +0200
commitf27c38ab5d90f68c9dd60cabef248a570c0be8fc (patch)
tree1a8c52ee218e64ed777e51f97aeb02476670d44c
parent053cc9534d174dc89daba36724ed2dcb36755b90 (diff)
[2.2.x] 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
-rw-r--r--django/core/validators.py14
-rw-r--r--docs/releases/2.2.24.txt13
-rw-r--r--tests/validators/invalid_urls.txt8
-rw-r--r--tests/validators/tests.py20
-rw-r--r--tests/validators/valid_urls.txt6
5 files changed, 60 insertions, 1 deletions
diff --git a/django/core/validators.py b/django/core/validators.py
index d32b54f68c..2da0688e28 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -75,7 +75,7 @@ class URLValidator(RegexValidator):
ul = '\u00a1-\uffff' # unicode letters range (must not be a raw string)
# 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)
# Host patterns
@@ -256,6 +256,18 @@ def validate_ipv4_address(value):
ipaddress.IPv4Address(value)
except ValueError:
raise ValidationError(_('Enter a valid IPv4 address.'), code='invalid')
+ 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',
+ )
def validate_ipv6_address(value):
diff --git a/docs/releases/2.2.24.txt b/docs/releases/2.2.24.txt
index 9bcf7037c4..1064fc53a0 100644
--- a/docs/releases/2.2.24.txt
+++ b/docs/releases/2.2.24.txt
@@ -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
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+.
diff --git a/tests/validators/invalid_urls.txt b/tests/validators/invalid_urls.txt
index 4a092034ff..a5a41ba845 100644
--- a/tests/validators/invalid_urls.txt
+++ b/tests/validators/invalid_urls.txt
@@ -46,6 +46,14 @@ http://1.1.1.1.1
http://123.123.123
http://3628126748
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://[::1:2::3]:8080/
diff --git a/tests/validators/tests.py b/tests/validators/tests.py
index 012b098f4e..1f09fb53fc 100644
--- a/tests/validators/tests.py
+++ b/tests/validators/tests.py
@@ -135,6 +135,16 @@ TEST_DATA = [
(validate_ipv4_address, '1.1.1.1\n', 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
# is tested in much greater detail in its own testcase
(validate_ipv6_address, 'fe80::1', None),
@@ -160,6 +170,16 @@ TEST_DATA = [
(validate_ipv46_address, '::zzz', 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, '12', None),
(validate_comma_separated_integer_list, '1,2', None),
diff --git a/tests/validators/valid_urls.txt b/tests/validators/valid_urls.txt
index f79f948142..ef9e563f8e 100644
--- a/tests/validators/valid_urls.txt
+++ b/tests/validators/valid_urls.txt
@@ -63,6 +63,12 @@ http://0.0.0.0/
http://255.255.255.255
http://224.0.0.0
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://example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com
http://example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa