Loading django/http/multipartparser.py +3 −2 Original line number Diff line number Diff line Loading @@ -181,10 +181,11 @@ class MultiPartParser(object): elif item_type == FILE: # This is a file, use the handler... file_name = disposition.get('filename') if not file_name: continue if file_name: file_name = force_text(file_name, encoding, errors='replace') file_name = self.IE_sanitize(unescape_entities(file_name)) if not file_name: continue content_type, content_type_extra = meta_data.get('content-type', ('', {})) content_type = content_type.strip() Loading docs/releases/1.8.12.txt +3 −1 Original line number Diff line number Diff line Loading @@ -9,4 +9,6 @@ Django 1.8.12 fixes several bugs in 1.8.11. Bugfixes ======== * ... * Made ``MultiPartParser`` ignore filenames that normalize to an empty string to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input (:ticket:`26325`). docs/releases/1.9.5.txt +3 −1 Original line number Diff line number Diff line Loading @@ -9,4 +9,6 @@ Django 1.9.5 fixes several bugs in 1.9.4. Bugfixes ======== * ... * Made ``MultiPartParser`` ignore filenames that normalize to an empty string to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input (:ticket:`26325`). tests/file_uploads/tests.py +35 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,41 @@ class FileUploadTests(TestCase): response = self.client.request(**r) self.assertEqual(response.status_code, 200) def test_blank_filenames(self): """ Receiving file upload when filename is blank (before and after sanitization) should be okay. """ # The second value is normalized to an empty name by # MultiPartParser.IE_sanitize() filenames = ['', 'C:\\Windows\\'] payload = client.FakePayload() for i, name in enumerate(filenames): payload.write('\r\n'.join([ '--' + client.BOUNDARY, 'Content-Disposition: form-data; name="file%s"; filename="%s"' % (i, 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) self.assertEqual(response.status_code, 200) # Empty filenames should be ignored received = json.loads(response.content.decode('utf-8')) for i, name in enumerate(filenames): self.assertIsNone(received.get('file%s' % i)) 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 Loading Loading
django/http/multipartparser.py +3 −2 Original line number Diff line number Diff line Loading @@ -181,10 +181,11 @@ class MultiPartParser(object): elif item_type == FILE: # This is a file, use the handler... file_name = disposition.get('filename') if not file_name: continue if file_name: file_name = force_text(file_name, encoding, errors='replace') file_name = self.IE_sanitize(unescape_entities(file_name)) if not file_name: continue content_type, content_type_extra = meta_data.get('content-type', ('', {})) content_type = content_type.strip() Loading
docs/releases/1.8.12.txt +3 −1 Original line number Diff line number Diff line Loading @@ -9,4 +9,6 @@ Django 1.8.12 fixes several bugs in 1.8.11. Bugfixes ======== * ... * Made ``MultiPartParser`` ignore filenames that normalize to an empty string to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input (:ticket:`26325`).
docs/releases/1.9.5.txt +3 −1 Original line number Diff line number Diff line Loading @@ -9,4 +9,6 @@ Django 1.9.5 fixes several bugs in 1.9.4. Bugfixes ======== * ... * Made ``MultiPartParser`` ignore filenames that normalize to an empty string to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input (:ticket:`26325`).
tests/file_uploads/tests.py +35 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,41 @@ class FileUploadTests(TestCase): response = self.client.request(**r) self.assertEqual(response.status_code, 200) def test_blank_filenames(self): """ Receiving file upload when filename is blank (before and after sanitization) should be okay. """ # The second value is normalized to an empty name by # MultiPartParser.IE_sanitize() filenames = ['', 'C:\\Windows\\'] payload = client.FakePayload() for i, name in enumerate(filenames): payload.write('\r\n'.join([ '--' + client.BOUNDARY, 'Content-Disposition: form-data; name="file%s"; filename="%s"' % (i, 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) self.assertEqual(response.status_code, 200) # Empty filenames should be ignored received = json.loads(response.content.decode('utf-8')) for i, name in enumerate(filenames): self.assertIsNone(received.get('file%s' % i)) 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 Loading