Commit b38637d5 authored by Claude Paroz's avatar Claude Paroz
Browse files

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.
parent b0a58b90
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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()