[1.11.x] 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
ed682a24fc
commit
869b34e9b3
@ -237,13 +237,16 @@ def repercent_broken_unicode(path):
|
||||
we need to re-percent-encode any octet produced that is not part of a
|
||||
strictly legal UTF-8 octet sequence.
|
||||
"""
|
||||
try:
|
||||
path.decode('utf-8')
|
||||
except UnicodeDecodeError as e:
|
||||
repercent = quote(path[e.start:e.end], safe=b"/#%[]=:;$&()+,!?*@'~")
|
||||
path = repercent_broken_unicode(
|
||||
path[:e.start] + force_bytes(repercent) + path[e.end:])
|
||||
return path
|
||||
while True:
|
||||
try:
|
||||
path.decode('utf-8')
|
||||
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"/#%[]=:;$&()+,!?*@'~")
|
||||
path = path[:e.start] + force_bytes(repercent) + path[e.end:]
|
||||
else:
|
||||
return path
|
||||
|
||||
|
||||
def filepath_to_uri(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`
|
||||
were subject to SQL injection, using a suitably crafted dictionary, with
|
||||
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.
|
||||
|
@ -2,12 +2,13 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from django.utils import six
|
||||
from django.utils.encoding import (
|
||||
escape_uri_path, filepath_to_uri, force_bytes, force_text, iri_to_uri,
|
||||
smart_text, uri_to_iri,
|
||||
repercent_broken_unicode, smart_text, uri_to_iri,
|
||||
)
|
||||
from django.utils.functional import SimpleLazyObject
|
||||
from django.utils.http import urlquote_plus
|
||||
@ -76,6 +77,15 @@ class TestEncodingUtils(unittest.TestCase):
|
||||
self.assertEqual(smart_text(1), '1')
|
||||
self.assertEqual(smart_text('foo'), 'foo')
|
||||
|
||||
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):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user