summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHrushikesh Vaidya <hrushikeshrv@gmail.com>2022-01-17 14:42:48 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-20 07:19:52 +0100
commit3fadf141e66c8d0baaa66574fa3b63c4d3655482 (patch)
treefb04627e74070eb488e6efb35af4f1d4d32e1909
parent0f6946495a8ec955b471ca1baaf408ceb53d4796 (diff)
Fixed #33062 -- Made MultiPartParser remove non-printable chars from file names.
-rw-r--r--django/http/multipartparser.py2
-rw-r--r--tests/file_uploads/tests.py23
2 files changed, 25 insertions, 0 deletions
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index ddf7cfa2f6..c3cb90e639 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -320,6 +320,8 @@ class MultiPartParser:
file_name = html.unescape(file_name)
file_name = file_name.rsplit('/')[-1]
file_name = file_name.rsplit('\\')[-1]
+ # Remove non-printable characters.
+ file_name = ''.join([char for char in file_name if char.isprintable()])
if file_name in {'', '.', '..'}:
return None
diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py
index 145d714a76..1e20b48d25 100644
--- a/tests/file_uploads/tests.py
+++ b/tests/file_uploads/tests.py
@@ -283,6 +283,29 @@ class FileUploadTests(TestCase):
for i, name in enumerate(filenames):
self.assertIsNone(received.get('file%s' % i))
+ def test_non_printable_chars_in_file_names(self):
+ file_name = 'non-\x00printable\x00\n_chars.txt\x00'
+ payload = client.FakePayload()
+ payload.write('\r\n'.join([
+ '--' + client.BOUNDARY,
+ f'Content-Disposition: form-data; name="file"; filename="{file_name}"',
+ 'Content-Type: application/octet-stream',
+ '',
+ 'You got pwnd.\r\n'
+ ]))
+ payload.write('\r\n--' + client.BOUNDARY + '--\r\n')
+ r = {
+ 'CONTENT_LENGTH': len(payload),
+ 'CONTENT_TYPE': client.MULTIPART_CONTENT,
+ 'PATH_INFO': '/echo/',
+ 'REQUEST_METHOD': 'POST',
+ 'wsgi.input': payload,
+ }
+ response = self.client.request(**r)
+ # Non-printable chars are sanitized.
+ received = response.json()
+ self.assertEqual(received['file'], 'non-printable_chars.txt')
+
def test_dangerous_file_names(self):
"""Uploaded file names should be sanitized before ever reaching the view."""
# This test simulates possible directory traversal attacks by a