mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[3.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
This commit is contained in:
		
				
					committed by
					
						 Carlton Gibson
						Carlton Gibson
					
				
			
			
				
	
			
			
			
						parent
						
							dfaba12cda
						
					
				
				
					commit
					9f75e2e562
				
			| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user