+30
-4
lines changedFilter options
+30
-4
lines changed Original file line number Diff line number Diff line change
@@ -229,16 +229,18 @@ def repercent_broken_unicode(path):
229
229
repercent-encode any octet produced that is not part of a strictly legal
230
230
UTF-8 octet sequence.
231
231
"""
232
+
changed_parts = []
232
233
while True:
233
234
try:
234
235
path.decode()
235
236
except UnicodeDecodeError as e:
236
237
# CVE-2019-14235: A recursion shouldn't be used since the exception
237
238
# handling uses massive amounts of memory
238
239
repercent = quote(path[e.start:e.end], safe=b"/#%[]=:;$&()+,!?*@'~")
239
-
path = path[:e.start] + repercent.encode() + path[e.end:]
240
+
changed_parts.append(path[:e.start] + repercent.encode())
241
+
path = path[e.end:]
240
242
else:
241
-
return path
243
+
return b"".join(changed_parts) + path
242
244
243
245
244
246
def filepath_to_uri(path):
Original file line number Diff line number Diff line change
@@ -6,4 +6,9 @@ Django 3.2.21 release notes
6
6
7
7
Django 3.2.21 fixes a security issue with severity "moderate" in 3.2.20.
8
8
9
-
...
9
+
CVE-2023-41164: Potential denial of service vulnerability in ``django.utils.encoding.uri_to_iri()``
10
+
===================================================================================================
11
+
12
+
``django.utils.encoding.uri_to_iri()`` was subject to potential denial of
13
+
service attack via certain inputs with a very large number of Unicode
14
+
characters.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
1
1
import datetime
2
+
import inspect
2
3
import sys
3
4
import unittest
4
5
from pathlib import Path
5
6
from unittest import mock
6
-
from urllib.parse import quote_plus
7
+
from urllib.parse import quote, quote_plus
7
8
8
9
from django.test import SimpleTestCase
9
10
from django.utils.encoding import (
@@ -101,6 +102,24 @@ def test_repercent_broken_unicode_recursion_error(self):
101
102
except RecursionError:
102
103
self.fail('Unexpected RecursionError raised.')
103
104
105
+
def test_repercent_broken_unicode_small_fragments(self):
106
+
data = b"test\xfctest\xfctest\xfc"
107
+
decoded_paths = []
108
+
109
+
def mock_quote(*args, **kwargs):
110
+
# The second frame is the call to repercent_broken_unicode().
111
+
decoded_paths.append(inspect.currentframe().f_back.f_locals["path"])
112
+
return quote(*args, **kwargs)
113
+
114
+
with mock.patch("django.utils.encoding.quote", mock_quote):
115
+
self.assertEqual(repercent_broken_unicode(data), b"test%FCtest%FCtest%FC")
116
+
117
+
# decode() is called on smaller fragment of the path each time.
118
+
self.assertEqual(
119
+
decoded_paths,
120
+
[b"test\xfctest\xfctest\xfc", b"test\xfctest\xfc", b"test\xfc"],
121
+
)
122
+
104
123
105
124
class TestRFC3987IEncodingUtils(unittest.TestCase):
106
125
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4