Przeglądaj źródła

Fixed #23887 -- Returned Bad Request for multipart parsing fails

Thanks Antti Häyrynen and Tim Graham for the report, and Aymeric
Augustin for the review.
Claude Paroz 10 lat temu
rodzic
commit
b38637d581

+ 10 - 0
django/core/handlers/base.py

@@ -10,6 +10,7 @@ from django.core import urlresolvers
 from django.core import signals
 from django.core.exceptions import MiddlewareNotUsed, PermissionDenied, SuspiciousOperation
 from django.db import connections, transaction
+from django.http.multipartparser import MultiPartParserError
 from django.utils.encoding import force_text
 from django.utils.module_loading import import_string
 from django.utils import six
@@ -176,6 +177,15 @@ class BaseHandler(object):
                 })
             response = self.get_exception_response(request, resolver, 403)
 
+        except MultiPartParserError:
+            logger.warning(
+                'Bad request (Unable to parse request body): %s', request.path,
+                extra={
+                    'status_code': 400,
+                    'request': request
+                })
+            response = self.get_exception_response(request, resolver, 400)
+
         except SuspiciousOperation as e:
             # The request logger receives events for any problematic request
             # The security logger receives events for all SuspiciousOperations

+ 13 - 0
tests/handlers/tests.py

@@ -93,6 +93,19 @@ class HandlerTests(TestCase):
         # latest versions.
         self.assertIsInstance(request.COOKIES, dict)
 
+    @override_settings(ROOT_URLCONF='handlers.urls')
+    def test_invalid_multipart_boundary(self):
+        """
+        Invalid boundary string should produce a "Bad Request" response, not a
+        server error (#23887).
+        """
+        environ = RequestFactory().post('/malformed_post/').environ
+        environ['CONTENT_TYPE'] = 'multipart/form-data; boundary=WRONG\x07'
+        handler = WSGIHandler()
+        response = handler(environ, lambda *a, **k: None)
+        # Expect "bad request" response
+        self.assertEqual(response.status_code, 400)
+
 
 @override_settings(ROOT_URLCONF='handlers.urls')
 class TransactionsPerRequestTests(TransactionTestCase):

+ 1 - 0
tests/handlers/urls.py

@@ -10,4 +10,5 @@ urlpatterns = [
     url(r'^in_transaction/$', views.in_transaction),
     url(r'^not_in_transaction/$', views.not_in_transaction),
     url(r'^suspicious/$', views.suspicious),
+    url(r'^malformed_post/$', views.malformed_post),
 ]

+ 7 - 0
tests/handlers/views.py

@@ -3,6 +3,7 @@ from __future__ import unicode_literals
 from django.core.exceptions import SuspiciousOperation
 from django.db import connection, transaction
 from django.http import HttpResponse, StreamingHttpResponse
+from django.views.decorators.csrf import csrf_exempt
 
 
 def regular(request):
@@ -24,3 +25,9 @@ def not_in_transaction(request):
 
 def suspicious(request):
     raise SuspiciousOperation('dubious')
+
+
+@csrf_exempt
+def malformed_post(request):
+    request.POST
+    return HttpResponse()