Fixed CVE-2019-14235 -- Fixed potential memory exhaustion in django.utils.encoding.uri_to_iri().
Thanks to Guido Vranken for initial report.
This commit is contained in:
parent
7deeabc7c7
commit
76ed1c49f8
|
@ -229,12 +229,15 @@ def repercent_broken_unicode(path):
|
||||||
repercent-encode any octet produced that is not part of a strictly legal
|
repercent-encode any octet produced that is not part of a strictly legal
|
||||||
UTF-8 octet sequence.
|
UTF-8 octet sequence.
|
||||||
"""
|
"""
|
||||||
|
while True:
|
||||||
try:
|
try:
|
||||||
path.decode()
|
path.decode()
|
||||||
except UnicodeDecodeError as e:
|
except UnicodeDecodeError as e:
|
||||||
|
# CVE-2019-14235: A recursion shouldn't be used since the exception
|
||||||
|
# handling uses massive amounts of memory
|
||||||
repercent = quote(path[e.start:e.end], safe=b"/#%[]=:;$&()+,!?*@'~")
|
repercent = quote(path[e.start:e.end], safe=b"/#%[]=:;$&()+,!?*@'~")
|
||||||
path = repercent_broken_unicode(
|
path = path[:e.start] + force_bytes(repercent) + path[e.end:]
|
||||||
path[:e.start] + force_bytes(repercent) + path[e.end:])
|
else:
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,3 +45,13 @@ CVE-2019-14234: SQL injection possibility in key and index lookups for ``JSONFie
|
||||||
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
||||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||||
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
||||||
|
|
||||||
|
CVE-2019-14235: Potential memory exhaustion in ``django.utils.encoding.uri_to_iri()``
|
||||||
|
=====================================================================================
|
||||||
|
|
||||||
|
If passed certain inputs, :func:`django.utils.encoding.uri_to_iri` could lead
|
||||||
|
to significant memory usage due to excessive recursion when re-percent-encoding
|
||||||
|
invalid UTF-8 octet sequences.
|
||||||
|
|
||||||
|
``uri_to_iri()`` now avoids recursion when re-percent-encoding invalid UTF-8
|
||||||
|
octet sequences.
|
||||||
|
|
|
@ -45,3 +45,13 @@ CVE-2019-14234: SQL injection possibility in key and index lookups for ``JSONFie
|
||||||
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
<hstorefield.key>` for :class:`~django.contrib.postgres.fields.HStoreField`
|
||||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||||
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
||||||
|
|
||||||
|
CVE-2019-14235: Potential memory exhaustion in ``django.utils.encoding.uri_to_iri()``
|
||||||
|
=====================================================================================
|
||||||
|
|
||||||
|
If passed certain inputs, :func:`django.utils.encoding.uri_to_iri` could lead
|
||||||
|
to significant memory usage due to excessive recursion when re-percent-encoding
|
||||||
|
invalid UTF-8 octet sequences.
|
||||||
|
|
||||||
|
``uri_to_iri()`` now avoids recursion when re-percent-encoding invalid UTF-8
|
||||||
|
octet sequences.
|
||||||
|
|
|
@ -46,6 +46,16 @@ CVE-2019-14234: SQL injection possibility in key and index lookups for ``JSONFie
|
||||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||||
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
dictionary expansion, as the ``**kwargs`` passed to ``QuerySet.filter()``.
|
||||||
|
|
||||||
|
CVE-2019-14235: Potential memory exhaustion in ``django.utils.encoding.uri_to_iri()``
|
||||||
|
=====================================================================================
|
||||||
|
|
||||||
|
If passed certain inputs, :func:`django.utils.encoding.uri_to_iri` could lead
|
||||||
|
to significant memory usage due to excessive recursion when re-percent-encoding
|
||||||
|
invalid UTF-8 octet sequences.
|
||||||
|
|
||||||
|
``uri_to_iri()`` now avoids recursion when re-percent-encoding invalid UTF-8
|
||||||
|
octet sequences.
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from urllib.parse import quote_plus
|
from urllib.parse import quote_plus
|
||||||
|
@ -6,8 +7,8 @@ from urllib.parse import quote_plus
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils.encoding import (
|
from django.utils.encoding import (
|
||||||
DjangoUnicodeDecodeError, escape_uri_path, filepath_to_uri, force_bytes,
|
DjangoUnicodeDecodeError, escape_uri_path, filepath_to_uri, force_bytes,
|
||||||
force_str, get_system_encoding, iri_to_uri, smart_bytes, smart_str,
|
force_str, get_system_encoding, iri_to_uri, repercent_broken_unicode,
|
||||||
uri_to_iri,
|
smart_bytes, smart_str, uri_to_iri,
|
||||||
)
|
)
|
||||||
from django.utils.functional import SimpleLazyObject
|
from django.utils.functional import SimpleLazyObject
|
||||||
from django.utils.translation import gettext_lazy
|
from django.utils.translation import gettext_lazy
|
||||||
|
@ -90,6 +91,15 @@ class TestEncodingUtils(SimpleTestCase):
|
||||||
with mock.patch('locale.getdefaultlocale', side_effect=Exception):
|
with mock.patch('locale.getdefaultlocale', side_effect=Exception):
|
||||||
self.assertEqual(get_system_encoding(), 'ascii')
|
self.assertEqual(get_system_encoding(), 'ascii')
|
||||||
|
|
||||||
|
def test_repercent_broken_unicode_recursion_error(self):
|
||||||
|
# Prepare a string long enough to force a recursion error if the tested
|
||||||
|
# function uses recursion.
|
||||||
|
data = b'\xfc' * sys.getrecursionlimit()
|
||||||
|
try:
|
||||||
|
self.assertEqual(repercent_broken_unicode(data), b'%FC' * sys.getrecursionlimit())
|
||||||
|
except RecursionError:
|
||||||
|
self.fail('Unexpected RecursionError raised.')
|
||||||
|
|
||||||
|
|
||||||
class TestRFC3987IEncodingUtils(unittest.TestCase):
|
class TestRFC3987IEncodingUtils(unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue