mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +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). | ||||
|  | ||||
|     # 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 | ||||
| @@ -276,6 +276,19 @@ def validate_ipv4_address(value): | ||||
|         ipaddress.IPv4Address(value) | ||||
|     except ValueError: | ||||
|         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): | ||||
|   | ||||
| @@ -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+. | ||||
|   | ||||
| @@ -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+. | ||||
|   | ||||
| @@ -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 | ||||
| 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 | ||||
| ======== | ||||
|  | ||||
|   | ||||
| @@ -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/ | ||||
|   | ||||
| @@ -136,6 +136,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), | ||||
| @@ -161,6 +171,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), | ||||
|   | ||||
| @@ -71,6 +71,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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user