VYPR
High severityNVD Advisory· Published Jun 8, 2021· Updated Aug 3, 2024

CVE-2021-33571

CVE-2021-33571

Description

In Django 2.2 before 2.2.24, 3.x before 3.1.12, and 3.2 before 3.2.4, URLValidator, validate_ipv4_address, and validate_ipv46_address do not prohibit leading zero characters in octal literals. This may allow a bypass of access control that is based on IP addresses. (validate_ipv4_address and validate_ipv46_address are unaffected with Python 3.9.5+..) .

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In Django, URLValidator and IP validators accept leading zeros in IPv4 octets, allowing bypass of IP-based access controls via octal interpretation.

Vulnerability

In Django versions 2.2 before 2.2.24, 3.x before 3.1.12, and 3.2 before 3.2.4, the URLValidator, validate_ipv4_address, and validate_ipv46_address functions do not prohibit leading zero characters in IPv4 octets [1][2]. When such an IP address is parsed by Python's ipaddress module (except in Python 3.9.5+), leading zeros cause the octet to be interpreted as an octal number, which can result in a different IP address than intended [3].

Exploitation

An attacker can supply an IPv4 address with leading zeros (e.g., 192.168.1.001) that passes Django's validation. If the application uses this validation to enforce IP-based access controls, the attacker can bypass restrictions by providing an octal representation that resolves to a different IP address than the one allowed [4]. No authentication or user interaction is required; the attacker only needs network access to send the crafted input.

Impact

Successful exploitation allows an attacker to bypass IP-based access controls, potentially gaining unauthorized access to restricted resources or services. The impact is limited to scenarios where access control decisions depend solely on validated IP addresses [2].

Mitigation

Upgrade to Django 2.2.24, 3.1.12, or 3.2.4, which reject IP addresses with leading zeros [1][4]. No workaround is available for unpatched versions. The vulnerability is also mitigated on Python 3.9.5+, but upgrading Django is recommended to ensure consistent behavior [3].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
>= 2.2a1, < 2.2.242.2.24
DjangoPyPI
>= 3.0a1, < 3.1.123.1.12
DjangoPyPI
>= 3.2a1, < 3.2.43.2.4

Affected products

166

Patches

3
f27c38ab5d90

[2.2.x] Fixed CVE-2021-33571 -- Prevented leading zeros in IPv4 addresses.

https://github.com/django/djangoMariusz FelisiakMay 25, 2021via ghsa
5 files changed · +60 1
  • django/core/validators.py+13 1 modified
    @@ -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):
    
  • docs/releases/2.2.24.txt+13 0 modified
    @@ -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+.
    
  • tests/validators/invalid_urls.txt+8 0 modified
    @@ -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/
    
  • tests/validators/tests.py+20 0 modified
    @@ -135,6 +135,16 @@
         (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 @@
         (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),
    
  • tests/validators/valid_urls.txt+6 0 modified
    @@ -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
    
9f75e2e562fa

[3.2.x] Fixed CVE-2021-33571 -- Prevented leading zeros in IPv4 addresses.

https://github.com/django/djangoMariusz FelisiakMay 24, 2021via ghsa
7 files changed · +87 1
  • django/core/validators.py+14 1 modified
    @@ -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):
    
  • docs/releases/2.2.24.txt+13 0 modified
    @@ -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+.
    
  • docs/releases/3.1.12.txt+13 0 modified
    @@ -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+.
    
  • docs/releases/3.2.4.txt+13 0 modified
    @@ -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
     ========
     
    
  • tests/validators/invalid_urls.txt+8 0 modified
    @@ -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/
    
  • tests/validators/tests.py+20 0 modified
    @@ -136,6 +136,16 @@
         (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 @@
         (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),
    
  • tests/validators/valid_urls.txt+6 0 modified
    @@ -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
    
203d4ab9ebcd

[3.1.x] Fixed CVE-2021-33571 -- Prevented leading zeros in IPv4 addresses.

https://github.com/django/djangoMariusz FelisiakMay 24, 2021via ghsa
6 files changed · +73 1
  • django/core/validators.py+13 1 modified
    @@ -64,7 +64,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
    @@ -247,6 +247,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):
    
  • docs/releases/2.2.24.txt+13 0 modified
    @@ -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+.
    
  • docs/releases/3.1.12.txt+13 0 modified
    @@ -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+.
    
  • tests/validators/invalid_urls.txt+8 0 modified
    @@ -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/
    
  • tests/validators/tests.py+20 0 modified
    @@ -135,6 +135,16 @@
         (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 @@
         (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),
    
  • tests/validators/valid_urls.txt+6 0 modified
    @@ -67,6 +67,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
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

16

News mentions

0

No linked articles in our index yet.