mirror of https://github.com/django/django.git
Fixed #32329 -- Made CsrfViewMiddleware catch more specific UnreadablePostError.
Thanks Chris Jerdonek for the review.
This commit is contained in:
parent
852fa7617e
commit
00ea883ef5
|
@ -11,6 +11,7 @@ from urllib.parse import urlparse
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import DisallowedHost, ImproperlyConfigured
|
from django.core.exceptions import DisallowedHost, ImproperlyConfigured
|
||||||
|
from django.http import UnreadablePostError
|
||||||
from django.http.request import HttpHeaders
|
from django.http.request import HttpHeaders
|
||||||
from django.urls import get_callable
|
from django.urls import get_callable
|
||||||
from django.utils.cache import patch_vary_headers
|
from django.utils.cache import patch_vary_headers
|
||||||
|
@ -342,7 +343,7 @@ class CsrfViewMiddleware(MiddlewareMixin):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
try:
|
try:
|
||||||
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
|
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
|
||||||
except OSError:
|
except UnreadablePostError:
|
||||||
# Handle a broken connection before we've completed reading the
|
# Handle a broken connection before we've completed reading the
|
||||||
# POST data. process_view shouldn't raise any exceptions, so
|
# POST data. process_view shouldn't raise any exceptions, so
|
||||||
# we'll ignore and serve the user a 403 (assuming they're still
|
# we'll ignore and serve the user a 403 (assuming they're still
|
||||||
|
|
|
@ -3,7 +3,7 @@ import re
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.sessions.backends.cache import SessionStore
|
from django.contrib.sessions.backends.cache import SessionStore
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse, UnreadablePostError
|
||||||
from django.middleware.csrf import (
|
from django.middleware.csrf import (
|
||||||
CSRF_ALLOWED_CHARS, CSRF_SESSION_KEY, CSRF_TOKEN_LENGTH, REASON_BAD_ORIGIN,
|
CSRF_ALLOWED_CHARS, CSRF_SESSION_KEY, CSRF_TOKEN_LENGTH, REASON_BAD_ORIGIN,
|
||||||
REASON_CSRF_TOKEN_MISSING, REASON_NO_CSRF_COOKIE, CsrfViewMiddleware,
|
REASON_CSRF_TOKEN_MISSING, REASON_NO_CSRF_COOKIE, CsrfViewMiddleware,
|
||||||
|
@ -728,10 +728,10 @@ class CsrfViewMiddlewareTestMixin:
|
||||||
req = self._get_request()
|
req = self._get_request()
|
||||||
ensure_csrf_cookie_view(req)
|
ensure_csrf_cookie_view(req)
|
||||||
|
|
||||||
def test_post_data_read_failure(self):
|
def test_reading_post_data_raises_unreadable_post_error(self):
|
||||||
"""
|
"""
|
||||||
OSErrors during POST data reading are caught and treated as if the
|
An UnreadablePostError raised while reading the POST data should be
|
||||||
POST data wasn't there.
|
handled by the middleware.
|
||||||
"""
|
"""
|
||||||
req = self._get_POST_request_with_token()
|
req = self._get_POST_request_with_token()
|
||||||
mw = CsrfViewMiddleware(post_form_view)
|
mw = CsrfViewMiddleware(post_form_view)
|
||||||
|
@ -740,7 +740,7 @@ class CsrfViewMiddlewareTestMixin:
|
||||||
self.assertIsNone(resp)
|
self.assertIsNone(resp)
|
||||||
|
|
||||||
req = self._get_POST_request_with_token(request_class=PostErrorRequest)
|
req = self._get_POST_request_with_token(request_class=PostErrorRequest)
|
||||||
req.post_error = OSError('error reading input data')
|
req.post_error = UnreadablePostError('Error reading input data.')
|
||||||
mw.process_request(req)
|
mw.process_request(req)
|
||||||
with self.assertLogs('django.security.csrf', 'WARNING') as cm:
|
with self.assertLogs('django.security.csrf', 'WARNING') as cm:
|
||||||
resp = mw.process_view(req, post_form_view, (), {})
|
resp = mw.process_view(req, post_form_view, (), {})
|
||||||
|
@ -750,6 +750,18 @@ class CsrfViewMiddlewareTestMixin:
|
||||||
'Forbidden (%s): ' % REASON_CSRF_TOKEN_MISSING,
|
'Forbidden (%s): ' % REASON_CSRF_TOKEN_MISSING,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_reading_post_data_raises_os_error(self):
|
||||||
|
"""
|
||||||
|
An OSError raised while reading the POST data should not be handled by
|
||||||
|
the middleware.
|
||||||
|
"""
|
||||||
|
mw = CsrfViewMiddleware(post_form_view)
|
||||||
|
req = self._get_POST_request_with_token(request_class=PostErrorRequest)
|
||||||
|
req.post_error = OSError('Deleted directories/Missing permissions.')
|
||||||
|
mw.process_request(req)
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
mw.process_view(req, post_form_view, (), {})
|
||||||
|
|
||||||
@override_settings(ALLOWED_HOSTS=['www.example.com'])
|
@override_settings(ALLOWED_HOSTS=['www.example.com'])
|
||||||
def test_bad_origin_bad_domain(self):
|
def test_bad_origin_bad_domain(self):
|
||||||
"""A request with a bad origin is rejected."""
|
"""A request with a bad origin is rejected."""
|
||||||
|
|
Loading…
Reference in New Issue