Fixed #26325 -- Made MultiPartParser ignore filenames that normalize to an empty string.
This commit is contained in:
parent
75614f6d4c
commit
4b129ac81f
|
@ -181,10 +181,11 @@ class MultiPartParser(object):
|
||||||
elif item_type == FILE:
|
elif item_type == FILE:
|
||||||
# This is a file, use the handler...
|
# This is a file, use the handler...
|
||||||
file_name = disposition.get('filename')
|
file_name = disposition.get('filename')
|
||||||
|
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:
|
if not file_name:
|
||||||
continue
|
continue
|
||||||
file_name = force_text(file_name, encoding, errors='replace')
|
|
||||||
file_name = self.IE_sanitize(unescape_entities(file_name))
|
|
||||||
|
|
||||||
content_type, content_type_extra = meta_data.get('content-type', ('', {}))
|
content_type, content_type_extra = meta_data.get('content-type', ('', {}))
|
||||||
content_type = content_type.strip()
|
content_type = content_type.strip()
|
||||||
|
|
|
@ -9,4 +9,6 @@ Django 1.8.12 fixes several bugs in 1.8.11.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Made ``MultiPartParser`` ignore filenames that normalize to an empty string
|
||||||
|
to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input
|
||||||
|
(:ticket:`26325`).
|
||||||
|
|
|
@ -9,4 +9,6 @@ Django 1.9.5 fixes several bugs in 1.9.4.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Made ``MultiPartParser`` ignore filenames that normalize to an empty string
|
||||||
|
to fix crash in ``MemoryFileUploadHandler`` on specially crafted user input
|
||||||
|
(:ticket:`26325`).
|
||||||
|
|
|
@ -179,6 +179,41 @@ class FileUploadTests(TestCase):
|
||||||
response = self.client.request(**r)
|
response = self.client.request(**r)
|
||||||
self.assertEqual(response.status_code, 200)
|
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):
|
def test_dangerous_file_names(self):
|
||||||
"""Uploaded file names should be sanitized before ever reaching the view."""
|
"""Uploaded file names should be sanitized before ever reaching the view."""
|
||||||
# This test simulates possible directory traversal attacks by a
|
# This test simulates possible directory traversal attacks by a
|
||||||
|
|
Loading…
Reference in New Issue