Пример #1
0
    def _https_referer_replace(self, request):
        """
        When https is enabled, django CSRF checking includes referer checking
        which breaks when using CORS. This function updates the HTTP_REFERER
        header to make sure it matches HTTP_HOST, provided that our cors logic
        succeeds
        """
        origin = request.META.get('HTTP_ORIGIN')

        if (request.is_secure() and origin
                and 'ORIGINAL_HTTP_REFERER' not in request.META):
            settings = get_active_settings(request)
            url = urlparse(origin)
            if (not settings.CORS_ORIGIN_ALLOW_ALL
                    and self.origin_not_found_in_white_lists(
                        origin, url, settings)):
                return

            try:
                http_referer = request.META['HTTP_REFERER']
                http_host = "https://%s/" % request.META['HTTP_HOST']
                request.META = request.META.copy()
                request.META['ORIGINAL_HTTP_REFERER'] = http_referer
                request.META['HTTP_REFERER'] = http_host
            except KeyError:
                pass
Пример #2
0
    def _https_referer_replace(self, request):
        """
        When https is enabled, django CSRF checking includes referer checking
        which breaks when using CORS. This function updates the HTTP_REFERER
        header to make sure it matches HTTP_HOST, provided that our cors logic
        succeeds
        """
        origin = request.META.get('HTTP_ORIGIN')

        if (request.is_secure() and origin and
                'ORIGINAL_HTTP_REFERER' not in request.META):
            settings = get_active_settings(request)
            url = urlparse(origin)
            if (not settings.CORS_ORIGIN_ALLOW_ALL and
                    self.origin_not_found_in_white_lists(
                        origin, url, settings)):
                return

            try:
                http_referer = request.META['HTTP_REFERER']
                http_host = "https://%s/" % request.META['HTTP_HOST']
                request.META = request.META.copy()
                request.META['ORIGINAL_HTTP_REFERER'] = http_referer
                request.META['HTTP_REFERER'] = http_host
            except KeyError:
                pass
Пример #3
0
 def process_view(self, request, callback, callback_args, callback_kwargs):
     """
     Do the referer replacement here as well
     """
     settings = get_active_settings(request)
     if (self.is_enabled(request, settings)
             and settings.CORS_REPLACE_HTTPS_REFERER):
         self._https_referer_replace(request)
     return None
Пример #4
0
 def process_view(self, request, callback, callback_args, callback_kwargs):
     """
     Do the referer replacement here as well
     """
     settings = get_active_settings(request)
     if (self.is_enabled(request, settings) and
             settings.CORS_REPLACE_HTTPS_REFERER):
         self._https_referer_replace(request)
     return None
Пример #5
0
 def test_returns_matching_settings(self):
     endpoint_overrides = [
         (r'^/restricted/.*$', {
             'CORS_ALLOW_CREDENTIALS': True,
         }),
     ]
     with override_settings(CORS_ENDPOINT_OVERRIDES=endpoint_overrides):
         request = Mock(path='/restricted/foo', META={'HTTP_ORIGIN': 'http://foo.google.com'})
         active_settings = get_active_settings(request)
         assert active_settings.CORS_ALLOW_CREDENTIALS is True
Пример #6
0
 def _https_referer_replace_reverse(self, request):
     """
     Put the HTTP_REFERER back to its original value and delete the
     temporary storage
     """
     settings = get_active_settings(request)
     if (settings.CORS_REPLACE_HTTPS_REFERER
             and 'ORIGINAL_HTTP_REFERER' in request.META):
         http_referer = request.META['ORIGINAL_HTTP_REFERER']
         request.META['HTTP_REFERER'] = http_referer
         del request.META['ORIGINAL_HTTP_REFERER']
Пример #7
0
 def _https_referer_replace_reverse(self, request):
     """
     Put the HTTP_REFERER back to its original value and delete the
     temporary storage
     """
     settings = get_active_settings(request)
     if (settings.CORS_REPLACE_HTTPS_REFERER and
             'ORIGINAL_HTTP_REFERER' in request.META):
         http_referer = request.META['ORIGINAL_HTTP_REFERER']
         request.META['HTTP_REFERER'] = http_referer
         del request.META['ORIGINAL_HTTP_REFERER']
Пример #8
0
    def process_request(self, request):
        """
        If CORS preflight header, then create an
        empty body response (200 OK) and return it

        Django won't bother calling any other request
        view/exception middleware along with the requested view;
        it will call any response middlewares
        """
        settings = get_active_settings(request)
        if (self.is_enabled(request, settings)
                and settings.CORS_REPLACE_HTTPS_REFERER):
            self._https_referer_replace(request)

        if (self.is_enabled(request, settings) and request.method == 'OPTIONS'
                and "HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META):
            response = http.HttpResponse()
            return response
        return None
Пример #9
0
    def process_request(self, request):
        """
        If CORS preflight header, then create an
        empty body response (200 OK) and return it

        Django won't bother calling any other request
        view/exception middleware along with the requested view;
        it will call any response middlewares
        """
        settings = get_active_settings(request)
        if (self.is_enabled(request, settings) and
                settings.CORS_REPLACE_HTTPS_REFERER):
            self._https_referer_replace(request)

        if (self.is_enabled(request, settings) and
                request.method == 'OPTIONS' and
                "HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META):
            response = http.HttpResponse()
            return response
        return None
Пример #10
0
    def process_response(self, request, response):
        """
        Add the respective CORS headers
        """
        origin = request.META.get('HTTP_ORIGIN')
        settings = get_active_settings(request)
        if self.is_enabled(request, settings) and origin:
            # todo: check hostname from db instead
            url = urlparse(origin)

            if settings.CORS_MODEL is not None:
                model = get_model(*settings.CORS_MODEL.split('.'))
                if model.objects.filter(cors=url.netloc).exists():
                    response[ACCESS_CONTROL_ALLOW_ORIGIN] = origin

            if (not settings.CORS_ORIGIN_ALLOW_ALL
                    and self.origin_not_found_in_white_lists(
                        origin, url, settings)):
                return response

            response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*" if (
                settings.CORS_ORIGIN_ALLOW_ALL
                and not settings.CORS_ALLOW_CREDENTIALS) else origin

            if len(settings.CORS_EXPOSE_HEADERS):
                response[ACCESS_CONTROL_EXPOSE_HEADERS] = ', '.join(
                    settings.CORS_EXPOSE_HEADERS)

            if settings.CORS_ALLOW_CREDENTIALS:
                response[ACCESS_CONTROL_ALLOW_CREDENTIALS] = 'true'

            if request.method == 'OPTIONS':
                response[ACCESS_CONTROL_ALLOW_HEADERS] = ', '.join(
                    settings.CORS_ALLOW_HEADERS)
                response[ACCESS_CONTROL_ALLOW_METHODS] = ', '.join(
                    settings.CORS_ALLOW_METHODS)
                if settings.CORS_PREFLIGHT_MAX_AGE:
                    response[ACCESS_CONTROL_MAX_AGE] = \
                        settings.CORS_PREFLIGHT_MAX_AGE

        return response
Пример #11
0
    def process_response(self, request, response):
        """
        Add the respective CORS headers
        """
        origin = request.META.get('HTTP_ORIGIN')
        settings = get_active_settings(request)
        if self.is_enabled(request, settings) and origin:
            # todo: check hostname from db instead
            url = urlparse(origin)

            if settings.CORS_MODEL is not None:
                model = get_model(*settings.CORS_MODEL.split('.'))
                if model.objects.filter(cors=url.netloc).exists():
                    response[ACCESS_CONTROL_ALLOW_ORIGIN] = origin

            if (not settings.CORS_ORIGIN_ALLOW_ALL and
                    self.origin_not_found_in_white_lists(
                        origin, url, settings)):
                return response

            response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*" if (
                settings.CORS_ORIGIN_ALLOW_ALL and
                not settings.CORS_ALLOW_CREDENTIALS) else origin

            if len(settings.CORS_EXPOSE_HEADERS):
                response[ACCESS_CONTROL_EXPOSE_HEADERS] = ', '.join(
                    settings.CORS_EXPOSE_HEADERS)

            if settings.CORS_ALLOW_CREDENTIALS:
                response[ACCESS_CONTROL_ALLOW_CREDENTIALS] = 'true'

            if request.method == 'OPTIONS':
                response[ACCESS_CONTROL_ALLOW_HEADERS] = ', '.join(
                    settings.CORS_ALLOW_HEADERS)
                response[ACCESS_CONTROL_ALLOW_METHODS] = ', '.join(
                    settings.CORS_ALLOW_METHODS)
                if settings.CORS_PREFLIGHT_MAX_AGE:
                    response[ACCESS_CONTROL_MAX_AGE] = \
                        settings.CORS_PREFLIGHT_MAX_AGE

        return response
Пример #12
0
 def test_returns_defaults_with_basic_config(self):
     request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foo.google.com'})
     active_settings = get_active_settings(request)
     assert active_settings.CORS_ALLOW_CREDENTIALS is False