Ticket #26325: fix-multipart-file-upload.diff

File fix-multipart-file-upload.diff, 2.7 KB (added by jmb202, 9 years ago)

Proposed fix

  • django/http/multipartparser.py

    diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
    index 375584e..67d0fc4 100644
    a b class MultiPartParser(object):  
    181181                elif item_type == FILE:
    182182                    # This is a file, use the handler...
    183183                    file_name = disposition.get('filename')
     184                    if file_name:
     185                        file_name = force_text(file_name, encoding, errors='replace')
     186                        file_name = self.IE_sanitize(unescape_entities(file_name))
    184187                    if not file_name:
    185188                        continue
    186                     file_name = force_text(file_name, encoding, errors='replace')
    187                     file_name = self.IE_sanitize(unescape_entities(file_name))
    188189
    189190                    content_type, content_type_extra = meta_data.get('content-type', ('', {}))
    190191                    content_type = content_type.strip()
  • tests/file_uploads/tests.py

    diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py
    index 4888ca5..41df6a6 100644
    a b class FileUploadTests(TestCase):  
    174174        response = self.client.request(**r)
    175175        self.assertEqual(response.status_code, 200)
    176176
     177    def test_blank_filenames(self):
     178        """
     179        Test receiving file upload when filename is blank (before or after sanitisation)
     180        """
     181        filenames = [
     182            "",
     183            "C:\\Windows\\",
     184        ]
     185
     186        payload = client.FakePayload()
     187        for i, name in enumerate(filenames):
     188            payload.write('\r\n'.join([
     189                '--' + client.BOUNDARY,
     190                'Content-Disposition: form-data; name="file%s"; filename="%s"' % (i, name),
     191                'Content-Type: application/octet-stream',
     192                '',
     193                'You got pwnd.\r\n'
     194            ]))
     195        payload.write('\r\n--' + client.BOUNDARY + '--\r\n')
     196
     197        r = {
     198            'CONTENT_LENGTH': len(payload),
     199            'CONTENT_TYPE': client.MULTIPART_CONTENT,
     200            'PATH_INFO': "/echo/",
     201            'REQUEST_METHOD': 'POST',
     202            'wsgi.input': payload,
     203        }
     204        response = self.client.request(**r)
     205        self.assertEqual(response.status_code, 200)
     206
     207        # Empty filenames should be ignored
     208        received = json.loads(response.content.decode('utf-8'))
     209        for i, name in enumerate(filenames):
     210            self.assertEqual(received.get('file%s' % i, None), None)
     211
    177212    def test_dangerous_file_names(self):
    178213        """Uploaded file names should be sanitized before ever reaching the view."""
    179214        # This test simulates possible directory traversal attacks by a
Back to Top