mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #32713, Fixed CVE-2021-32052 -- Prevented newlines and tabs from being accepted in URLValidator on Python 3.9.5+.
In Python 3.9.5+ urllib.parse() automatically removes ASCII newlines
and tabs from URLs [1, 2]. Unfortunately it created an issue in
the URLValidator. URLValidator uses urllib.urlsplit() and
urllib.urlunsplit() for creating a URL variant with Punycode which no
longer contains newlines and tabs in Python 3.9.5+. As a consequence,
the regular expression matched the URL (without unsafe characters) and
the source value (with unsafe characters) was considered valid.
[1] https://bugs.python.org/issue43882 and
[2] 76cd81d603
This commit is contained in:
parent
a708f39ce6
commit
e1e81aa1c4
@ -92,6 +92,7 @@ class URLValidator(RegexValidator):
|
|||||||
r'\Z', re.IGNORECASE)
|
r'\Z', re.IGNORECASE)
|
||||||
message = _('Enter a valid URL.')
|
message = _('Enter a valid URL.')
|
||||||
schemes = ['http', 'https', 'ftp', 'ftps']
|
schemes = ['http', 'https', 'ftp', 'ftps']
|
||||||
|
unsafe_chars = frozenset('\t\r\n')
|
||||||
|
|
||||||
def __init__(self, schemes=None, **kwargs):
|
def __init__(self, schemes=None, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
@ -101,6 +102,8 @@ class URLValidator(RegexValidator):
|
|||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
raise ValidationError(self.message, code=self.code, params={'value': value})
|
raise ValidationError(self.message, code=self.code, params={'value': value})
|
||||||
|
if self.unsafe_chars.intersection(value):
|
||||||
|
raise ValidationError(self.message, code=self.code, params={'value': value})
|
||||||
# Check if the scheme is valid.
|
# Check if the scheme is valid.
|
||||||
scheme = value.split('://')[0].lower()
|
scheme = value.split('://')[0].lower()
|
||||||
if scheme not in self.schemes:
|
if scheme not in self.schemes:
|
||||||
|
22
docs/releases/2.2.22.txt
Normal file
22
docs/releases/2.2.22.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
===========================
|
||||||
|
Django 2.2.22 release notes
|
||||||
|
===========================
|
||||||
|
|
||||||
|
*May 6, 2021*
|
||||||
|
|
||||||
|
Django 2.2.22 fixes a security issue in 2.2.21.
|
||||||
|
|
||||||
|
CVE-2021-32052: Header injection possibility since ``URLValidator`` accepted newlines in input on Python 3.9.5+
|
||||||
|
===============================================================================================================
|
||||||
|
|
||||||
|
On Python 3.9.5+, :class:`~django.core.validators.URLValidator` didn't prohibit
|
||||||
|
newlines and tabs. If you used values with newlines in HTTP response, you could
|
||||||
|
suffer from header injection attacks. Django itself wasn't vulnerable because
|
||||||
|
:class:`~django.http.HttpResponse` prohibits newlines in HTTP headers.
|
||||||
|
|
||||||
|
Moreover, the ``URLField`` form field which uses ``URLValidator`` silently
|
||||||
|
removes newlines and tabs on Python 3.9.5+, so the possibility of newlines
|
||||||
|
entering your data only existed if you are using this validator outside of the
|
||||||
|
form fields.
|
||||||
|
|
||||||
|
This issue was introduced by the :bpo:`43882` fix.
|
22
docs/releases/3.1.10.txt
Normal file
22
docs/releases/3.1.10.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
===========================
|
||||||
|
Django 3.1.10 release notes
|
||||||
|
===========================
|
||||||
|
|
||||||
|
*May 6, 2021*
|
||||||
|
|
||||||
|
Django 3.1.10 fixes a security issue in 3.1.9.
|
||||||
|
|
||||||
|
CVE-2021-32052: Header injection possibility since ``URLValidator`` accepted newlines in input on Python 3.9.5+
|
||||||
|
===============================================================================================================
|
||||||
|
|
||||||
|
On Python 3.9.5+, :class:`~django.core.validators.URLValidator` didn't prohibit
|
||||||
|
newlines and tabs. If you used values with newlines in HTTP response, you could
|
||||||
|
suffer from header injection attacks. Django itself wasn't vulnerable because
|
||||||
|
:class:`~django.http.HttpResponse` prohibits newlines in HTTP headers.
|
||||||
|
|
||||||
|
Moreover, the ``URLField`` form field which uses ``URLValidator`` silently
|
||||||
|
removes newlines and tabs on Python 3.9.5+, so the possibility of newlines
|
||||||
|
entering your data only existed if you are using this validator outside of the
|
||||||
|
form fields.
|
||||||
|
|
||||||
|
This issue was introduced by the :bpo:`43882` fix.
|
@ -2,9 +2,24 @@
|
|||||||
Django 3.2.2 release notes
|
Django 3.2.2 release notes
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
*Expected June 1, 2021*
|
*May 6, 2021*
|
||||||
|
|
||||||
Django 3.2.2 fixes several bugs in 3.2.1.
|
Django 3.2.2 fixes a security issue and a bug in 3.2.1.
|
||||||
|
|
||||||
|
CVE-2021-32052: Header injection possibility since ``URLValidator`` accepted newlines in input on Python 3.9.5+
|
||||||
|
===============================================================================================================
|
||||||
|
|
||||||
|
On Python 3.9.5+, :class:`~django.core.validators.URLValidator` didn't prohibit
|
||||||
|
newlines and tabs. If you used values with newlines in HTTP response, you could
|
||||||
|
suffer from header injection attacks. Django itself wasn't vulnerable because
|
||||||
|
:class:`~django.http.HttpResponse` prohibits newlines in HTTP headers.
|
||||||
|
|
||||||
|
Moreover, the ``URLField`` form field which uses ``URLValidator`` silently
|
||||||
|
removes newlines and tabs on Python 3.9.5+, so the possibility of newlines
|
||||||
|
entering your data only existed if you are using this validator outside of the
|
||||||
|
form fields.
|
||||||
|
|
||||||
|
This issue was introduced by the :bpo:`43882` fix.
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
@ -41,6 +41,7 @@ versions of the documentation contain the release notes for any later releases.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
3.1.10
|
||||||
3.1.9
|
3.1.9
|
||||||
3.1.8
|
3.1.8
|
||||||
3.1.7
|
3.1.7
|
||||||
@ -78,6 +79,7 @@ versions of the documentation contain the release notes for any later releases.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
2.2.22
|
||||||
2.2.21
|
2.2.21
|
||||||
2.2.20
|
2.2.20
|
||||||
2.2.19
|
2.2.19
|
||||||
|
@ -226,9 +226,15 @@ TEST_DATA = [
|
|||||||
(URLValidator(), None, ValidationError),
|
(URLValidator(), None, ValidationError),
|
||||||
(URLValidator(), 56, ValidationError),
|
(URLValidator(), 56, ValidationError),
|
||||||
(URLValidator(), 'no_scheme', ValidationError),
|
(URLValidator(), 'no_scheme', ValidationError),
|
||||||
# Trailing newlines not accepted
|
# Newlines and tabs are not accepted.
|
||||||
(URLValidator(), 'http://www.djangoproject.com/\n', ValidationError),
|
(URLValidator(), 'http://www.djangoproject.com/\n', ValidationError),
|
||||||
(URLValidator(), 'http://[::ffff:192.9.5.5]\n', ValidationError),
|
(URLValidator(), 'http://[::ffff:192.9.5.5]\n', ValidationError),
|
||||||
|
(URLValidator(), 'http://www.djangoproject.com/\r', ValidationError),
|
||||||
|
(URLValidator(), 'http://[::ffff:192.9.5.5]\r', ValidationError),
|
||||||
|
(URLValidator(), 'http://www.django\rproject.com/', ValidationError),
|
||||||
|
(URLValidator(), 'http://[::\rffff:192.9.5.5]', ValidationError),
|
||||||
|
(URLValidator(), 'http://\twww.djangoproject.com/', ValidationError),
|
||||||
|
(URLValidator(), 'http://\t[::ffff:192.9.5.5]', ValidationError),
|
||||||
# Trailing junk does not take forever to reject
|
# Trailing junk does not take forever to reject
|
||||||
(URLValidator(), 'http://www.asdasdasdasdsadfm.com.br ', ValidationError),
|
(URLValidator(), 'http://www.asdasdasdasdsadfm.com.br ', ValidationError),
|
||||||
(URLValidator(), 'http://www.asdasdasdasdsadfm.com.br z', ValidationError),
|
(URLValidator(), 'http://www.asdasdasdasdsadfm.com.br z', ValidationError),
|
||||||
|
Loading…
Reference in New Issue
Block a user