Răsfoiți Sursa

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 ani în urmă
părinte
comite
b38637d581
4 a modificat fișierele cu 31 adăugiri și 0 ștergeri
  1. 10 0
      django/core/handlers/base.py
  2. 13 0
      tests/handlers/tests.py
  3. 1 0
      tests/handlers/urls.py
  4. 7 0
      tests/handlers/views.py

+ 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()