summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVirtosu Bogdan <virtosu.bogdan@gmail.com>2021-07-23 12:26:22 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-07-23 13:10:41 +0200
commit00ea883ef56fb5e092cbe4a6f7ff2e7470886ac4 (patch)
treef3ac2d410b8fa12ef8bd19d38e3de38984327bf2
parent852fa7617e24a68a990eaf0f7a597edb434ffd76 (diff)
Fixed #32329 -- Made CsrfViewMiddleware catch more specific UnreadablePostError.
Thanks Chris Jerdonek for the review.
-rw-r--r--django/middleware/csrf.py3
-rw-r--r--tests/csrf_tests/tests.py22
2 files changed, 19 insertions, 6 deletions
diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py
index d103900bdf..f8b8cf1ca0 100644
--- a/django/middleware/csrf.py
+++ b/django/middleware/csrf.py
@@ -11,6 +11,7 @@ from urllib.parse import urlparse
from django.conf import settings
from django.core.exceptions import DisallowedHost, ImproperlyConfigured
+from django.http import UnreadablePostError
from django.http.request import HttpHeaders
from django.urls import get_callable
from django.utils.cache import patch_vary_headers
@@ -342,7 +343,7 @@ class CsrfViewMiddleware(MiddlewareMixin):
if request.method == 'POST':
try:
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
- except OSError:
+ except UnreadablePostError:
# Handle a broken connection before we've completed reading the
# POST data. process_view shouldn't raise any exceptions, so
# we'll ignore and serve the user a 403 (assuming they're still
diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py
index e823ff11ee..6ec0c6326a 100644
--- a/tests/csrf_tests/tests.py
+++ b/tests/csrf_tests/tests.py
@@ -3,7 +3,7 @@ import re
from django.conf import settings
from django.contrib.sessions.backends.cache import SessionStore
from django.core.exceptions import ImproperlyConfigured
-from django.http import HttpRequest, HttpResponse
+from django.http import HttpRequest, HttpResponse, UnreadablePostError
from django.middleware.csrf import (
CSRF_ALLOWED_CHARS, CSRF_SESSION_KEY, CSRF_TOKEN_LENGTH, REASON_BAD_ORIGIN,
REASON_CSRF_TOKEN_MISSING, REASON_NO_CSRF_COOKIE, CsrfViewMiddleware,
@@ -728,10 +728,10 @@ class CsrfViewMiddlewareTestMixin:
req = self._get_request()
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
- POST data wasn't there.
+ An UnreadablePostError raised while reading the POST data should be
+ handled by the middleware.
"""
req = self._get_POST_request_with_token()
mw = CsrfViewMiddleware(post_form_view)
@@ -740,7 +740,7 @@ class CsrfViewMiddlewareTestMixin:
self.assertIsNone(resp)
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)
with self.assertLogs('django.security.csrf', 'WARNING') as cm:
resp = mw.process_view(req, post_form_view, (), {})
@@ -750,6 +750,18 @@ class CsrfViewMiddlewareTestMixin:
'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'])
def test_bad_origin_bad_domain(self):
"""A request with a bad origin is rejected."""