Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #20128 -- Made CsrfViewMiddleware ignore IOError when reading P…

…OST data.

Thanks Walter Doekes.
  • Loading branch information...
commit 815e7a57216b3e6ef716e924016acb09633ea8d1 1 parent fd4ccd0
@timgraham timgraham authored
Showing with 50 additions and 1 deletion.
  1. +9 −1 django/middleware/csrf.py
  2. +41 −0 tests/csrf_tests/tests.py
View
10 django/middleware/csrf.py
@@ -167,7 +167,15 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
# Check non-cookie token for match.
request_csrf_token = ""
if request.method == "POST":
- request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
+ try:
+ request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
+ except IOError:
+ # 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 listening, which they probably
+ # aren't because of the error).
+ pass
if request_csrf_token == "":
# Fall back to X-CSRFToken, to make things easier for AJAX,
View
41 tests/csrf_tests/tests.py
@@ -428,3 +428,44 @@ def test_csrf_cookie_age_none(self):
resp2 = CsrfViewMiddleware().process_response(req, resp)
max_age = resp2.cookies.get('csrfcookie').get('max-age')
self.assertEqual(max_age, '')
+
+ def test_post_data_read_failure(self):
+ """
+ #20128 -- IOErrors during POST data reading should be caught and
+ treated as if the POST data wasn't there.
+ """
+ class CsrfPostRequest(HttpRequest):
+ """
+ HttpRequest that can raise an IOError when accessing POST data
+ """
+ def __init__(self, token, raise_error):
+ super(CsrfPostRequest, self).__init__()
+ self.method = 'POST'
+
+ self.raise_error = False
+ self.COOKIES[settings.CSRF_COOKIE_NAME] = token
+ self.POST['csrfmiddlewaretoken'] = token
+ self.raise_error = raise_error
+
+ def _load_post_and_files(self):
+ raise IOError('error reading input data')
+
+ def _get_post(self):
+ if self.raise_error:
+ self._load_post_and_files()
+ return self._post
+
+ def _set_post(self, post):
+ self._post = post
+
+ POST = property(_get_post, _set_post)
+
+ token = 'ABC'
+
+ req = CsrfPostRequest(token, raise_error=False)
+ resp = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
+ self.assertEqual(resp, None)
+
+ req = CsrfPostRequest(token, raise_error=True)
+ resp = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
+ self.assertEqual(resp.status_code, 403)
Please sign in to comment.
Something went wrong with that request. Please try again.