summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@pexip.com>2016-03-07 12:06:46 +0000
committerTim Graham <timograham@gmail.com>2016-03-07 13:22:11 -0500
commit809eb5ddeeca388b2a1d339f7d5ee1f29119ecea (patch)
tree772adf7d61f75f9c03c06392ed6d199f019f203a
parent4702c1ac98b284cacffcf5fbb0db9b85f0c2f8ba (diff)
[1.9.x] Fixed #26325 -- Made MultiPartParser ignore filenames that normalize to an empty string.
Backport of 4b129ac81f4fa38004950d0b307f81d1e9b44af8 from master
-rw-r--r--django/http/multipartparser.py5
-rw-r--r--docs/releases/1.8.12.txt4
-rw-r--r--docs/releases/1.9.5.txt4
-rw-r--r--tests/file_uploads/tests.py35
4 files changed, 44 insertions, 4 deletions
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 375584e4f3..67d0fc48d5 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -181,10 +181,11 @@ class MultiPartParser(object):
elif item_type == FILE:
# This is a file, use the handler...
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:
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.strip()
diff --git a/docs/releases/1.8.12.txt b/docs/releases/1.8.12.txt
index 332c6091a5..26735b8278 100644
--- a/docs/releases/1.8.12.txt
+++ b/docs/releases/1.8.12.txt
@@ -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`).
diff --git a/docs/releases/1.9.5.txt b/docs/releases/1.9.5.txt
index edff4db6bc..211cbba6ba 100644
--- a/docs/releases/1.9.5.txt
+++ b/docs/releases/1.9.5.txt
@@ -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`).
diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py
index ccecfce5c1..09c2c41c88 100644
--- a/tests/file_uploads/tests.py
+++ b/tests/file_uploads/tests.py
@@ -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