Exemple #1
0
def check_csrf(request: HttpRequest,
               callback: Callable) -> Optional[HttpResponseForbidden]:
    mware = CsrfViewMiddleware(
        lambda x: HttpResponseForbidden())  # pragma: no cover
    request.csrf_processing_done = False  # type: ignore
    mware.process_request(request)
    return mware.process_view(request, callback, (), {})
Exemple #2
0
 def test_no_session_on_request(self):
     msg = (
         'CSRF_USE_SESSIONS is enabled, but request.session is not set. '
         'SessionMiddleware must appear before CsrfViewMiddleware in MIDDLEWARE.'
     )
     with self.assertRaisesMessage(ImproperlyConfigured, msg):
         mw = CsrfViewMiddleware(lambda req: HttpResponse())
         mw.process_request(HttpRequest())
Exemple #3
0
 def test_process_request_csrf_cookie_and_token(self):
     """
     If both a cookie and a token is present, the middleware lets it through.
     """
     req = self._get_POST_request_with_token()
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #4
0
 def _test_https_good_referer_matches_cookie_domain(self):
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META['HTTP_REFERER'] = 'https://foo.example.com/'
     req.META['SERVER_PORT'] = '443'
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     response = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(response)
Exemple #5
0
 def test_csrf_token_in_header(self):
     """
     The token may be passed in a header instead of in the form.
     """
     req = self._get_POST_csrf_cookie_request()
     req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #6
0
 def test_token_node_with_csrf_cookie(self):
     """
     CsrfTokenNode works when a CSRF cookie is set.
     """
     req = self._get_GET_csrf_cookie_request()
     mw = CsrfViewMiddleware(token_view)
     mw.process_request(req)
     mw.process_view(req, token_view, (), {})
     resp = token_view(req)
     self._check_token_present(resp)
Exemple #7
0
 def test_process_request_csrf_cookie_no_token_exempt_view(self):
     """
     If a CSRF cookie is present and no token, but the csrf_exempt decorator
     has been applied to the view, the middleware lets it through
     """
     req = self._get_POST_csrf_cookie_request()
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, csrf_exempt(post_form_view), (), {})
     self.assertIsNone(resp)
Exemple #8
0
 def test_get_token_for_exempt_view(self):
     """
     get_token still works for a view decorated with 'csrf_exempt'.
     """
     req = self._get_GET_csrf_cookie_request()
     mw = CsrfViewMiddleware(token_view)
     mw.process_request(req)
     mw.process_view(req, csrf_exempt(token_view), (), {})
     resp = token_view(req)
     self._check_token_present(resp)
Exemple #9
0
 def test_csrf_token_in_header_with_customized_name(self):
     """
     settings.CSRF_HEADER_NAME can be used to customize the CSRF header name
     """
     req = self._get_POST_csrf_cookie_request()
     req.META['HTTP_X_CSRFTOKEN_CUSTOMIZED'] = self._csrf_id
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #10
0
    def test_post_data_read_failure(self):
        """
        OSErrors during POST data reading are caught and treated as if the
        POST data wasn't there (#20128).
        """
        class CsrfPostRequest(HttpRequest):
            """
            HttpRequest that can raise an OSError when accessing POST data
            """
            def __init__(self, token, raise_error):
                super().__init__()
                self.method = 'POST'

                self.raise_error = False
                self.COOKIES[settings.CSRF_COOKIE_NAME] = token

                # Handle both cases here to prevent duplicate code in the
                # session tests.
                self.session = {}
                self.session[CSRF_SESSION_KEY] = token

                self.POST['csrfmiddlewaretoken'] = token
                self.raise_error = raise_error

            def _load_post_and_files(self):
                raise OSError('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' + self._csrf_id)[:CSRF_TOKEN_LENGTH]

        req = CsrfPostRequest(token, raise_error=False)
        mw = CsrfViewMiddleware(post_form_view)
        mw.process_request(req)
        resp = mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(resp)

        req = CsrfPostRequest(token, raise_error=True)
        mw.process_request(req)
        with self.assertLogs('django.security.csrf', 'WARNING') as cm:
            resp = mw.process_view(req, post_form_view, (), {})
        self.assertEqual(resp.status_code, 403)
        self.assertEqual(
            cm.records[0].getMessage(),
            'Forbidden (%s): ' % REASON_CSRF_TOKEN_MISSING,
        )
Exemple #11
0
 def test_process_request_csrf_cookie_no_token(self):
     """
     If a CSRF cookie is present but no token, the middleware rejects
     the incoming request.
     """
     req = self._get_POST_csrf_cookie_request()
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     with self.assertLogs('django.security.csrf', 'WARNING') as cm:
         resp = mw.process_view(req, post_form_view, (), {})
     self.assertEqual(403, resp.status_code)
     self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % REASON_BAD_TOKEN)
Exemple #12
0
 def test_process_request_no_csrf_cookie(self):
     """
     If no CSRF cookies is present, the middleware rejects the incoming
     request. This will stop login CSRF.
     """
     req = self._get_POST_no_csrf_cookie_request()
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     with self.assertLogs('django.security.csrf', 'WARNING') as cm:
         resp = mw.process_view(req, post_form_view, (), {})
     self.assertEqual(403, resp.status_code)
     self.assertEqual(cm.records[0].getMessage(), 'Forbidden (%s): ' % REASON_NO_CSRF_COOKIE)
Exemple #13
0
 def test_https_good_referer(self):
     """
     A POST HTTPS request with a good referer is accepted.
     """
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META['HTTP_HOST'] = 'www.example.com'
     req.META['HTTP_REFERER'] = 'https://www.example.com/somepage'
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #14
0
 def _check_bad_or_missing_token(self, token, expected):
     """Passing None for token includes no token."""
     if token is None:
         req = self._get_POST_csrf_cookie_request()
     else:
         req = self._get_POST_request_with_token(token=token)
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     with self.assertLogs('django.security.csrf', 'WARNING') as cm:
         resp = mw.process_view(req, post_form_view, (), {})
     self.assertEqual(403, resp.status_code)
     self.assertEqual(cm.records[0].getMessage(),
                      'Forbidden (%s): ' % expected)
Exemple #15
0
 def test_https_good_referer_malformed_host(self):
     """
     A POST HTTPS request is accepted if it receives a good referer with
     a bad host.
     """
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META['HTTP_HOST'] = '@malformed'
     req.META['HTTP_REFERER'] = 'https://dashboard.example.com/somepage'
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #16
0
 def enforce_csrf(self, request):
     """
     Enforce CSRF validation
     """
     check = CsrfViewMiddleware()
     # populates request.META['CSRF_COOKIE'], which is used in process_view()
     check.process_request(request)
     breakpoint()
     reason = check.process_view(request, None, (), {})
     print(reason)
     if reason:
         # CSRF failed, bail with explicit error message
         raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
Exemple #17
0
 def test_https_csrf_wildcard_trusted_origin_allowed(self):
     """
     A POST HTTPS request with a referer that matches a CSRF_TRUSTED_ORIGINS
     wildcard is accepted.
     """
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META['HTTP_HOST'] = 'www.example.com'
     req.META['HTTP_REFERER'] = 'https://dashboard.example.com'
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     response = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(response)
Exemple #18
0
 def _test_https_good_referer_behind_proxy(self):
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META.update({
         'HTTP_HOST': '10.0.0.2',
         'HTTP_REFERER': 'https://www.example.com/somepage',
         'SERVER_PORT': '8080',
         'HTTP_X_FORWARDED_HOST': 'www.example.com',
         'HTTP_X_FORWARDED_PORT': '443',
     })
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #19
0
 def test_https_good_referer_2(self):
     """
     A POST HTTPS request with a good referer is accepted where the referer
     contains no trailing slash.
     """
     # See ticket #15617
     req = self._get_POST_request_with_token()
     req._is_secure_override = True
     req.META['HTTP_HOST'] = 'www.example.com'
     req.META['HTTP_REFERER'] = 'https://www.example.com'
     mw = CsrfViewMiddleware(post_form_view)
     mw.process_request(req)
     resp = mw.process_view(req, post_form_view, (), {})
     self.assertIsNone(resp)
Exemple #20
0
 def test_bare_secret_accepted_and_replaced(self):
     """
     The csrf token is reset from a bare secret.
     """
     req = self._get_POST_bare_secret_csrf_cookie_request_with_token()
     mw = CsrfViewMiddleware(token_view)
     mw.process_request(req)
     resp = mw.process_view(req, token_view, (), {})
     self.assertIsNone(resp)
     resp = mw(req)
     self.assertIn(settings.CSRF_COOKIE_NAME, resp.cookies, "Cookie was not reset from bare secret")
     csrf_cookie = resp.cookies[settings.CSRF_COOKIE_NAME]
     self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)
     self._check_token_present(resp, csrf_id=csrf_cookie.value)
Exemple #21
0
 def test_cookie_not_reset_on_accepted_request(self):
     """
     The csrf token used in posts is changed on every request (although
     stays equivalent). The csrf cookie should not change on accepted
     requests. If it appears in the response, it should keep its value.
     """
     req = self._get_POST_request_with_token()
     mw = CsrfViewMiddleware(token_view)
     mw.process_request(req)
     mw.process_view(req, token_view, (), {})
     resp = mw(req)
     csrf_cookie = resp.cookies.get(settings.CSRF_COOKIE_NAME, None)
     if csrf_cookie:
         self.assertEqual(csrf_cookie.value, self._csrf_id_cookie,
                          "CSRF cookie was changed on an accepted request")
Exemple #22
0
    def test_put_and_delete_allowed(self):
        """
        HTTP PUT and DELETE can get through with X-CSRFToken and a cookie.
        """
        req = self._get_GET_csrf_cookie_request()
        req.method = 'PUT'
        req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
        mw = CsrfViewMiddleware(post_form_view)
        mw.process_request(req)
        resp = mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(resp)

        req = self._get_GET_csrf_cookie_request()
        req.method = 'DELETE'
        req.META['HTTP_X_CSRFTOKEN'] = self._csrf_id
        mw.process_request(req)
        resp = mw.process_view(req, post_form_view, (), {})
        self.assertIsNone(resp)
Exemple #23
0
    def test_process_response_get_token_not_used(self):
        """
        If get_token() is not called, the view middleware does not
        add a cookie.
        """
        # This is important to make pages cacheable.  Pages which do call
        # get_token(), assuming they use the token, are not cacheable because
        # the token is specific to the user
        req = self._get_GET_no_csrf_cookie_request()
        # non_token_view_using_request_processor does not call get_token(), but
        # does use the csrf request processor.  By using this, we are testing
        # that the view processor is properly lazy and doesn't call get_token()
        # until needed.
        mw = CsrfViewMiddleware(non_token_view_using_request_processor)
        mw.process_request(req)
        mw.process_view(req, non_token_view_using_request_processor, (), {})
        resp = mw(req)

        csrf_cookie = resp.cookies.get(settings.CSRF_COOKIE_NAME, False)
        self.assertIs(csrf_cookie, False)
Exemple #24
0
def check_csrf(request: HttpRequest, callback: Callable):
    mware = CsrfViewMiddleware(lambda: None)
    request.csrf_processing_done = False
    mware.process_request(request)
    return mware.process_view(request, callback, [], {})