Ejemplo n.º 1
0
    def test_improperly_configured(self, missing_setting):
        settings = {
            'FEATURES': {
                'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': True
            },
            'CROSS_DOMAIN_CSRF_COOKIE_NAME': self.COOKIE_NAME,
            'CROSS_DOMAIN_CSRF_COOKIE_DOMAIN': self.COOKIE_DOMAIN
        }
        del settings[missing_setting]

        with override_settings(**settings):
            with self.assertRaises(ImproperlyConfigured):
                CsrfCrossDomainCookieMiddleware()
Ejemplo n.º 2
0
 def setUp(self):
     super(TestCsrfCrossDomainCookieMiddleware, self).setUp()
     self.middleware = CsrfCrossDomainCookieMiddleware()
Ejemplo n.º 3
0
class TestCsrfCrossDomainCookieMiddleware(TestCase):
    """Tests for `CsrfCrossDomainCookieMiddleware`. """

    REFERER = 'https://www.example.com'
    COOKIE_NAME = 'shared-csrftoken'
    COOKIE_VALUE = 'abcd123'
    COOKIE_DOMAIN = '.edx.org'

    @override_settings(
        FEATURES={'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': True},
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN
    )
    def setUp(self):
        super(TestCsrfCrossDomainCookieMiddleware, self).setUp()
        self.middleware = CsrfCrossDomainCookieMiddleware()

    @override_settings(FEATURES={'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': False})
    def test_disabled_by_feature_flag(self):
        with self.assertRaises(MiddlewareNotUsed):
            CsrfCrossDomainCookieMiddleware()

    @ddt.data('CROSS_DOMAIN_CSRF_COOKIE_NAME', 'CROSS_DOMAIN_CSRF_COOKIE_DOMAIN')
    def test_improperly_configured(self, missing_setting):
        settings = {
            'FEATURES': {'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': True},
            'CROSS_DOMAIN_CSRF_COOKIE_NAME': self.COOKIE_NAME,
            'CROSS_DOMAIN_CSRF_COOKIE_DOMAIN': self.COOKIE_DOMAIN
        }
        del settings[missing_setting]

        with override_settings(**settings):
            with self.assertRaises(ImproperlyConfigured):
                CsrfCrossDomainCookieMiddleware()

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_ALLOW_ALL=True
    )
    def test_skip_if_not_secure(self):
        response = self._get_response(is_secure=False)
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_ALLOW_ALL=True
    )
    def test_skip_if_not_sending_csrf_token(self):
        response = self._get_response(csrf_cookie_used=False)
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_ALLOW_ALL=True
    )
    def test_skip_if_not_cross_domain_decorator(self):
        response = self._get_response(cross_domain_decorator=False)
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_WHITELIST=['other.example.com']
    )
    def test_skip_if_referer_not_whitelisted(self):
        response = self._get_response()
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN
    )
    def test_skip_if_not_cross_domain(self):
        response = self._get_response(
            referer="https://courses.edx.org/foo",
            host="courses.edx.org"
        )
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_ALLOW_ALL=True
    )
    def test_skip_if_no_referer(self):
        response = self._get_response(delete_referer=True)
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_ALLOW_ALL=True
    )
    def test_skip_if_referer_not_https(self):
        response = self._get_response(referer="http://www.example.com")
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_ALLOW_ALL=True
    )
    def test_skip_if_referer_no_protocol(self):
        response = self._get_response(referer="example.com")
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ALLOW_INSECURE=True
    )
    def test_skip_if_no_referer_insecure(self):
        response = self._get_response(delete_referer=True)
        self._assert_cookie_sent(response, False)

    @override_settings(
        CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
        CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
        CORS_ORIGIN_WHITELIST=['www.example.com']
    )
    def test_set_cross_domain_cookie(self):
        response = self._get_response()
        self._assert_cookie_sent(response, True)

    def _get_response(self,
                      is_secure=True,
                      csrf_cookie_used=True,
                      cross_domain_decorator=True,
                      referer=None,
                      host=None,
                      delete_referer=False):
        """Process a request using the middleware. """
        request = Mock()
        request.META = {
            'HTTP_REFERER': (
                referer if referer is not None
                else self.REFERER
            )
        }
        request.is_secure = lambda: is_secure

        if host is not None:
            request.get_host = lambda: host

        if delete_referer:
            del request.META['HTTP_REFERER']

        if csrf_cookie_used:
            request.META['CSRF_COOKIE_USED'] = True
            request.META['CSRF_COOKIE'] = self.COOKIE_VALUE

        if cross_domain_decorator:
            request.META['CROSS_DOMAIN_CSRF_COOKIE_USED'] = True

        return self.middleware.process_response(request, HttpResponse())

    def _assert_cookie_sent(self, response, is_set):
        """Check that the cross-domain CSRF cookie was sent. """
        if is_set:
            self.assertIn(self.COOKIE_NAME, response.cookies)
            cookie_header = str(response.cookies[self.COOKIE_NAME])

            expected = 'Set-Cookie: {name}={value}; Domain={domain};'.format(
                name=self.COOKIE_NAME,
                value=self.COOKIE_VALUE,
                domain=self.COOKIE_DOMAIN
            )
            self.assertIn(expected, cookie_header)
            self.assertIn('Max-Age=31449600; Path=/; secure', cookie_header)

        else:
            self.assertNotIn(self.COOKIE_NAME, response.cookies)
Ejemplo n.º 4
0
 def test_disabled_by_feature_flag(self):
     with self.assertRaises(MiddlewareNotUsed):
         CsrfCrossDomainCookieMiddleware()
Ejemplo n.º 5
0
 def setUp(self):
     super(TestCsrfCrossDomainCookieMiddleware, self).setUp()
     self.middleware = CsrfCrossDomainCookieMiddleware()
Ejemplo n.º 6
0
class TestCsrfCrossDomainCookieMiddleware(TestCase):
    """Tests for `CsrfCrossDomainCookieMiddleware`. """

    REFERER = 'https://www.example.com'
    COOKIE_NAME = 'shared-csrftoken'
    COOKIE_VALUE = 'abcd123'
    COOKIE_DOMAIN = '.edx.org'

    @override_settings(FEATURES={'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': True},
                       CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN)
    def setUp(self):
        super(TestCsrfCrossDomainCookieMiddleware, self).setUp()
        self.middleware = CsrfCrossDomainCookieMiddleware()

    @override_settings(FEATURES={'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': False})
    def test_disabled_by_feature_flag(self):
        with self.assertRaises(MiddlewareNotUsed):
            CsrfCrossDomainCookieMiddleware()

    @ddt.data('CROSS_DOMAIN_CSRF_COOKIE_NAME',
              'CROSS_DOMAIN_CSRF_COOKIE_DOMAIN')
    def test_improperly_configured(self, missing_setting):
        settings = {
            'FEATURES': {
                'ENABLE_CROSS_DOMAIN_CSRF_COOKIE': True
            },
            'CROSS_DOMAIN_CSRF_COOKIE_NAME': self.COOKIE_NAME,
            'CROSS_DOMAIN_CSRF_COOKIE_DOMAIN': self.COOKIE_DOMAIN
        }
        del settings[missing_setting]

        with override_settings(**settings):
            with self.assertRaises(ImproperlyConfigured):
                CsrfCrossDomainCookieMiddleware()

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_ALLOW_ALL=True)
    def test_skip_if_not_secure(self):
        response = self._get_response(is_secure=False)
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_ALLOW_ALL=True)
    def test_skip_if_not_sending_csrf_token(self):
        response = self._get_response(csrf_cookie_used=False)
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_ALLOW_ALL=True)
    def test_skip_if_not_cross_domain_decorator(self):
        response = self._get_response(cross_domain_decorator=False)
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_WHITELIST=['other.example.com'])
    def test_skip_if_referer_not_whitelisted(self):
        response = self._get_response()
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN)
    def test_skip_if_not_cross_domain(self):
        response = self._get_response(referer="https://courses.edx.org/foo",
                                      host="courses.edx.org")
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_ALLOW_ALL=True)
    def test_skip_if_no_referer(self):
        response = self._get_response(delete_referer=True)
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_ALLOW_ALL=True)
    def test_skip_if_referer_not_https(self):
        response = self._get_response(referer="http://www.example.com")
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_ALLOW_ALL=True)
    def test_skip_if_referer_no_protocol(self):
        response = self._get_response(referer="example.com")
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ALLOW_INSECURE=True)
    def test_skip_if_no_referer_insecure(self):
        response = self._get_response(delete_referer=True)
        self._assert_cookie_sent(response, False)

    @override_settings(CROSS_DOMAIN_CSRF_COOKIE_NAME=COOKIE_NAME,
                       CROSS_DOMAIN_CSRF_COOKIE_DOMAIN=COOKIE_DOMAIN,
                       CORS_ORIGIN_WHITELIST=['www.example.com'])
    def test_set_cross_domain_cookie(self):
        response = self._get_response()
        self._assert_cookie_sent(response, True)

    def _get_response(self,
                      is_secure=True,
                      csrf_cookie_used=True,
                      cross_domain_decorator=True,
                      referer=None,
                      host=None,
                      delete_referer=False):
        """Process a request using the middleware. """
        request = Mock()
        request.META = {
            'HTTP_REFERER': (referer if referer is not None else self.REFERER)
        }
        request.is_secure = lambda: is_secure

        if host is not None:
            request.get_host = lambda: host

        if delete_referer:
            del request.META['HTTP_REFERER']

        if csrf_cookie_used:
            request.META['CSRF_COOKIE_USED'] = True
            request.META['CSRF_COOKIE'] = self.COOKIE_VALUE

        if cross_domain_decorator:
            request.META['CROSS_DOMAIN_CSRF_COOKIE_USED'] = True

        return self.middleware.process_response(request, HttpResponse())

    def _assert_cookie_sent(self, response, is_set):
        """Check that the cross-domain CSRF cookie was sent. """
        if is_set:
            self.assertIn(self.COOKIE_NAME, response.cookies)
            cookie_header = str(response.cookies[self.COOKIE_NAME])

            expected = 'Set-Cookie: {name}={value}; Domain={domain};'.format(
                name=self.COOKIE_NAME,
                value=self.COOKIE_VALUE,
                domain=self.COOKIE_DOMAIN)
            self.assertIn(expected, cookie_header)
            self.assertIn('Max-Age=31449600; Path=/; secure', cookie_header)

        else:
            self.assertNotIn(self.COOKIE_NAME, response.cookies)