Ticket #20128: 20128.patch

File 20128.patch, 3.3 KB (added by Walter Doekes, 11 years ago)
  • django/middleware/csrf.py

    diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py
    index 4230344..0dda225 100644
    a b class CsrfViewMiddleware(object):  
    171171            # Check non-cookie token for match.
    172172            request_csrf_token = ""
    173173            if request.method == "POST":
    174                 request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
     174                try:
     175                    request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
     176                except IOError:
     177                    # Sometimes we get IOErrors due to a broken connection
     178                    # before we've completed reading the POST data. Process
     179                    # view middleware may not raise any exceptions, so we'll
     180                    # ignore and go on to serve the user a 403 (assuming he's
     181                    # still listening... which he probably isn't because of
     182                    # the IOError).
     183                    request_csrf_token = ""
    175184
    176185            if request_csrf_token == "":
    177186                # Fall back to X-CSRFToken, to make things easier for AJAX,
  • tests/csrf_tests/tests.py

    diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py
    index 5300b21..6a7e804 100644
    a b class TestingHttpRequest(HttpRequest):  
    4646    def is_secure(self):
    4747        return getattr(self, '_is_secure_override', False)
    4848
     49class BrokenHttpCsrfPostRequest(HttpRequest):
     50    """
     51    HttpRequest that can fail when accessing POST data
     52    """
     53    def __init__(self, token, is_broken):
     54        super(BrokenHttpCsrfPostRequest, self).__init__()
     55        self.method = 'POST'
     56
     57        self.is_broken = False
     58        self.COOKIES[settings.CSRF_COOKIE_NAME] = token
     59        self.POST['csrfmiddlewaretoken'] = token
     60        self.is_broken = is_broken
     61
     62    def _load_post_and_files(self):
     63        raise IOError('error reading input data')
     64
     65    def _get_post(self):
     66        if self.is_broken:
     67            # Break!
     68            self._load_post_and_files()
     69        assert hasattr(self, '_post')
     70        return self._post
     71
     72    def _set_post(self, post):
     73        self._post = post
     74
     75    POST = property(_get_post, _set_post)
     76
    4977class CsrfViewMiddlewareTest(TestCase):
    5078    # The csrf token is potentially from an untrusted source, so could have
    5179    # characters that need dealing with.
    class CsrfViewMiddlewareTest(TestCase):  
    340368        resp2 = CsrfViewMiddleware().process_response(req, resp)
    341369        self.assertTrue(resp2.cookies.get(settings.CSRF_COOKIE_NAME, False))
    342370        self.assertTrue('Cookie' in resp2.get('Vary',''))
     371
     372    def test_postdata_failure(self):
     373        """
     374        Tests that IOErrors during POST data reading are caught and
     375        treated as if the POST data wasn't there.
     376        """
     377        token = 'ABC'
     378
     379        # The is_broken flag is used as a self-test for the test.
     380        req = BrokenHttpCsrfPostRequest(token, is_broken=False)
     381        req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
     382        self.assertEqual(req2, None)
     383
     384        req = BrokenHttpCsrfPostRequest(token, is_broken=True)
     385        req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
     386        self.assertEqual(req2.status_code, 403)
Back to Top