def is_authenticated(self, request, **kwargs): """ Checks to make sure the user is logged in & has a Django session. """ # Cargo-culted from Django 1.3/1.4's ``django/middleware/csrf.py``. # We can't just use what's there, since the return values will be # wrong. # We also can't risk accessing ``request.POST``, which will break with # the serialized bodies. if request.method in ("GET", "HEAD", "OPTIONS", "TRACE"): return request.user.is_authenticated() if getattr(request, "_dont_enforce_csrf_checks", False): return request.user.is_authenticated() csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, "")) if request.is_secure(): referer = request.META.get("HTTP_REFERER") if referer is None: return False good_referer = "https://%s/" % request.get_host() if not same_origin(referer, good_referer): return False request_csrf_token = request.META.get("HTTP_X_CSRFTOKEN", "") request_csrf_token = _sanitize_token(request_csrf_token) if not constant_time_compare(unsalt_token(request_csrf_token), unsalt_token(csrf_token)): return False return request.user.is_authenticated()
def is_authenticated(self, request, **kwargs): ''' Checks to make sure the user is logged in and has a Django session. ''' if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): return bool(request.user.is_authenticated) if getattr(request, '_dont_enforce_csrf_checks', False): return bool(request.user.is_authenticated) csrf_token = _sanitize_token( request.COOKIES.get(settings.CSRF_COOKIE_NAME)) if csrf_token is None: logger.error('authentication rejected: NO CSRF cookie') return False elif DEBUG_AUTHENTICATION: logger.info('Found CSRF cookie: %r: %r', settings.CSRF_COOKIE_NAME, csrf_token) if request.is_secure(): if DEBUG_AUTHENTICATION: logger.info('perform secure session check.') if self._django_csrf_check(request) is not True: return False # Compare the session CSRF token to the posted CSRF token request_csrf_token = '' if request.method == 'POST': # Use the >1.4 Django Forms token key: "csrfmiddlewaretoken" try: request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') if DEBUG_AUTHENTICATION: logger.info( 'SessionAuthentication: POST csrf token (%r): %r', 'csrfmiddlewaretoken', request_csrf_token) except IOError: # Handle a broken connections pass if request_csrf_token == '': # Fall back to X-CSRFToken, used by Ajax clients request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if DEBUG_AUTHENTICATION: logger.info( 'SessionAuthentication: POST csrf token (%r): %r', 'HTTP_X_CSRFTOKEN', request_csrf_token) request_csrf_token = _sanitize_token(request_csrf_token) if not constant_time_compare(unsalt_token(request_csrf_token), unsalt_token(csrf_token)): logger.warn('CSRF tokens do not match: %r', request) return False return bool(request.user.is_authenticated)
def is_authenticated(self, request, **kwargs): ''' Checks to make sure the user is logged in and has a Django session. ''' if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): return bool(request.user.is_authenticated) if getattr(request, '_dont_enforce_csrf_checks', False): return bool(request.user.is_authenticated) csrf_token = _sanitize_token( request.COOKIES.get(settings.CSRF_COOKIE_NAME)) if csrf_token is None: logger.error('authentication rejected: NO CSRF cookie') return False elif DEBUG_AUTHENTICATION: logger.info('Found CSRF cookie: %r: %r', settings.CSRF_COOKIE_NAME, csrf_token) if request.is_secure(): if DEBUG_AUTHENTICATION: logger.info('perform secure session check.') if self._django_csrf_check(request) is not True: return False # Compare the session CSRF token to the posted CSRF token request_csrf_token = '' if request.method == 'POST': # Use the >1.4 Django Forms token key: "csrfmiddlewaretoken" try: request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') if DEBUG_AUTHENTICATION: logger.info( 'SessionAuthentication: POST csrf token (%r): %r', 'csrfmiddlewaretoken', request_csrf_token) except IOError: # Handle a broken connections pass if request_csrf_token == '': # Fall back to X-CSRFToken, used by Ajax clients request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if DEBUG_AUTHENTICATION: logger.info('SessionAuthentication: POST csrf token (%r): %r', 'HTTP_X_CSRFTOKEN', request_csrf_token) request_csrf_token = _sanitize_token(request_csrf_token) if not constant_time_compare(unsalt_token(request_csrf_token), unsalt_token(csrf_token)): logger.warn('CSRF tokens do not match: %r', request) return False return bool(request.user.is_authenticated)
def try_sessions(self, request, **kwargs): """ Attempt to authenticate with sessions. Cribbed from a newer version of Tastypie than we're using. """ csrf_token = _sanitize_token( request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return False good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): return False # Tastypie docstring says accessing POST here isn't safe, but so far it's not causing any problems... # This is necessary for downloads that post the csrf token from an iframe request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') or request.POST.get( 'csrfmiddlewaretoken', '') if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def try_sessions(self, request, **kwargs): """ Attempt to authenticate with sessions. Cribbed from a newer version of Tastypie than we're using. """ csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, "")) if request.is_secure(): referer = request.META.get("HTTP_REFERER") if referer is None: return False good_referer = "https://%s/" % request.get_host() if not same_origin(referer, good_referer): return False # Tastypie docstring says accessing POST here isn't safe, but so far it's not causing any problems... # This is necessary for downloads that post the csrf token from an iframe request_csrf_token = request.META.get("HTTP_X_CSRFTOKEN", "") or request.POST.get("csrfmiddlewaretoken", "") if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def is_authenticated(self, request, **kwargs): """ """ # this is the line i have to override in order to get # POST request to successfully authenticate ## if request.method in ('GET', 'POST', 'DELETE'): return request.user.is_authenticated() if getattr(request, '_dont_enforce_csrf_checks', False): return request.user.is_authenticated() csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return False good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): return False request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def is_authenticated(self, request, **kwargs): """ """ # this is the line i have to override in order to get # POST request to successfully authenticate ## if request.method in ("GET", "POST", "DELETE"): return request.user.is_authenticated() if getattr(request, "_dont_enforce_csrf_checks", False): return request.user.is_authenticated() csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, "")) if request.is_secure(): referer = request.META.get("HTTP_REFERER") if referer is None: return False good_referer = "https://%s/" % request.get_host() if not same_origin(referer, good_referer): return False request_csrf_token = request.META.get("HTTP_X_CSRFTOKEN", "") if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def is_authenticated(self, request, **kwargs): """ Checks to make sure the user is logged in & has a Django session. """ # Cargo-culted from Django 1.3/1.4's ``django/middleware/csrf.py``. # We can't just use what's there, since the return values will be # wrong. # We also can't risk accessing ``request.POST``, which will break with # the serialized bodies. if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): return request.user.is_authenticated() if getattr(request, '_dont_enforce_csrf_checks', False): return request.user.is_authenticated() csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return False good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): return False request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def is_authenticated(self, request, **kwargs): """ Checks to make sure the user is logged in & has a Django session. """ # Cargo-culted from Django 1.3/1.4's ``django/middleware/csrf.py``. # We can't just use what's there, since the return values will be # wrong. # We also can't risk accessing ``request.POST``, which will break with # the serialized bodies. if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): return request.user.is_authenticated() if getattr(request, '_dont_enforce_csrf_checks', False): return request.user.is_authenticated() csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return False good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): return False csrf_meta_name = getattr(settings, 'CSRF_META_NAME', 'HTTP_X_CSRFTOKEN') request_csrf_token = request.META.get(csrf_meta_name, '') if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def upload_status(request): if request.method == 'GET': if request.GET['key']: csrftoken = request.META.get( "CSRF_COOKIE") if "CSRF_COOKIE" in request.META else None cache_exist = cache.get(csrftoken) request_csrftoken = request.GET['key'] match = True try: from django.middleware.csrf import _sanitize_token, _compare_salted_tokens request_csrftoken = _sanitize_token(request_csrftoken) match = _compare_salted_tokens(request_csrftoken, csrftoken) except: pass if cache_exist and match: value = cache.get(csrftoken) return HttpResponse(json.dumps(value), content_type="application/json") elif not _compare_salted_tokens(key, csrftoken): return HttpResponse(json.dumps( {'error': "csrf value not match"}), content_type="application/json") else: return HttpResponse(json.dumps( {'error': "No csrf value in cache"}), content_type="application/json") else: return HttpResponse(json.dumps( {'error': 'No parameter key in GET request'}), content_type="application/json") else: return HttpResponse(json.dumps({'error': 'No GET request'}), content_type="application/json")
def is_authenticated(self, request, **kwargs): # this is the line i have to override in order to get # POST request to successfully authenticate ## if request.method in ['GET', 'POST', 'PATCH', 'DELETE']: return request.user.is_authenticated() if getattr(request, '_dont_enforce_csrf_checks', False): return request.user.is_authenticated() csrf_token = _sanitize_token( request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return False good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): return False request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): return False return request.user.is_authenticated()
def check_csrf_token(request, *args, **kwargs): csrf_token = _sanitize_token(request.GET.get(token_key, '')) match = _compare_salted_tokens( csrf_token, request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if not match: raise PermissionDenied else: return view_func(request, *args, **kwargs)
def check_csrf_token(request, *args, **kwargs): csrf_token = _sanitize_token(request.GET.get(token_key, "")) match = _compare_salted_tokens( csrf_token, request.COOKIES.get(settings.CSRF_COOKIE_NAME, "")) if not match and getattr(settings, "CSRF_VERIFY_TOKEN", True): raise PermissionDenied else: return view_func(request, *args, **kwargs)
def _get_token(): try: cookie_token = request.cookies[api_settings.CSRF_COOKIE_NAME] except KeyError: return None csrf_token = _sanitize_token(cookie_token) if csrf_token != cookie_token: # Cookie token needed to be replaced; # the cookie needs to be reset. g.csrf_cookie_needs_reset = True return csrf_token
def get_or_create_csrf_token(request): try: csrf_token = _sanitize_token( request.COOKIES[django_settings.CSRF_COOKIE_NAME]) # Use same token next time except KeyError: csrf_token = _get_new_csrf_key() # Generate token and store it in the request, so it's # available to the view. request.META['CSRF_COOKIE'] = csrf_token request.META['CSRF_COOKIE_USED'] = True return csrf_token
def process_view(self, request, callback, callback_args, callback_kwargs): referer = request.META.get('HTTP_REFERER') csrf_token = request.META.get('CSRF_COOKIE') if csrf_token is None: return self._reject(request, REASON_NO_CSRF_COOKIE) request_csrf_token = request.GET.get('state', '') request_csrf_token = _sanitize_token(request_csrf_token) if not _compare_salted_tokens(request_csrf_token, csrf_token): return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def token(request): request_csrf_token = "" if request.method == "POST": try: request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') except IOError: return HttpResponse('e') if request_csrf_token == "": request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '') request_csrf_token = _sanitize_token(request_csrf_token) if not _compare_salted_tokens(request_csrf_token, csrf_token): return HttpResponse(request, REASON_BAD_TOKEN)
def manual_csrf_check(request): """ Performs a CSRF check for a specific request. Useful for in-view CSRF checks. Returns an HTTP response in case of CSRF failure. """ try: csrf_token = _sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME] ) request.META['CSRF_COOKIE'] = csrf_token except KeyError: csrf_token = None request.META["CSRF_COOKIE"] = _get_new_csrf_key() if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return middleware._reject(request, REASON_NO_REFERER) good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) return middleware._reject(request, reason) if csrf_token is None: return middleware._reject(request, REASON_NO_CSRF_COOKIE) request_csrf_token = "" if request.method == "POST": request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') if request_csrf_token == "": request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): return middleware._reject(request, REASON_BAD_TOKEN)
def get_csrf_token(request): """ CsrfViewMiddleware.process_view is never called for cached responses, and we still need to provide a CSRF token as an ssi variable, we must make sure here that the CSRF token is in request.META['CSRF_COOKIE']. """ token = get_token(request) if token: # CSRF token is already in place, just return it. return token # Mimicking CsrfViewMiddleware.process_view. try: token = _sanitize_token(request.COOKIES[settings.CSRF_COOKIE_NAME]) request.META['CSRF_COOKIE'] = token except KeyError: # Create new CSRF token. rotate_token(request) token = get_token(request) return token
def is_authenticated(self, request, **kwargs): """Check for valid CSRF token""" # Cargo-culted from TastyPie (which itself was cargo-culted from Django) # However, we only want CSRF, all our anons are anon. if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): return True csrf_token = _sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, '')) if request.is_secure(): referer = request.META.get('HTTP_REFERER') if referer is None: return False good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): return False request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') return constant_time_compare(request_csrf_token, csrf_token)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: csrf_token = django_csrf._sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME]) # Use same token next time request.META['CSRF_COOKIE'] = csrf_token except KeyError: csrf_token = None # Generate token and store it in the request, so it's # available to the view. request.META["CSRF_COOKIE"] = django_csrf._get_new_csrf_key() # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC2616 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # nonce we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = force_text(request.META.get('HTTP_REFERER'), strings_only=True, errors='replace') if referer is None: return self._reject(request, django_csrf.REASON_NO_REFERER) # Here we generate a list of all acceptable HTTP referers, # including the current host since that has been validated # upstream. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) # Note that request.get_host() includes the port. good_hosts.append(request.get_host()) good_referers = [ 'https://{0}/'.format(host) for host in good_hosts ] if not any( same_origin(referer, host) for host in good_referers): reason = REASON_BAD_REFERER % referer return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. return self._reject(request, django_csrf.REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": 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, # and possible for PUT/DELETE. request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): return self._reject(request, django_csrf.REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: csrf_token = _sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME]) # Use same token next time request.META['CSRF_COOKIE'] = csrf_token except KeyError: csrf_token = None # Generate token and store it in the request, so it's # available to the view. request.META["CSRF_COOKIE"] = _get_new_csrf_key() # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC2616 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. logger.warning('Forbidden (%s): %s', REASON_NO_CSRF_COOKIE, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') if request_csrf_token == "": # Fall back to X-CSRFToken, to make things easier for AJAX, # and possible for PUT/DELETE. request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): logger.warning('Forbidden (%s): %s', REASON_BAD_TOKEN, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_BAD_TOKEN) resp = self._accept(request) request.META["CSRF_COOKIE_USED"] = True return resp
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: csrf_token = django_csrf._sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME]) # Use same token next time request.META['CSRF_COOKIE'] = csrf_token except KeyError: csrf_token = None # Generate token and store it in the request, so it's # available to the view. request.META["CSRF_COOKIE"] = django_csrf._get_new_csrf_key() # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC2616 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # nonce we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = force_text( request.META.get('HTTP_REFERER'), strings_only=True, errors='replace' ) if referer is None: return self._reject(request, django_csrf.REASON_NO_REFERER) # Here we generate a list of all acceptable HTTP referers, # including the current host since that has been validated # upstream. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) # Note that request.get_host() includes the port. good_hosts.append(request.get_host()) good_referers = ['https://{0}/'.format(host) for host in good_hosts] if not any(same_origin(referer, host) for host in good_referers): reason = REASON_BAD_REFERER % referer return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. return self._reject(request, django_csrf.REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": 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, # and possible for PUT/DELETE. request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): return self._reject(request, django_csrf.REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, "csrf_processing_done", False): return None # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, "csrf_exempt", False): return None # Assume that anything not defined as 'safe' by RFC7231 needs protection if request.method not in ("GET", "HEAD", "OPTIONS", "TRACE"): if getattr(request, "_dont_enforce_csrf_checks", False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # secret we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = request.META.get("HTTP_REFERER") # -- Change from original here -- # # Only checks referer if it is present. # It's not a failure condition if the referer is not present. # Our site is HTTPS-only which does not need to rely on # referer checking. Above example does not apply. if referer is not None: referer = urlparse(referer) # Make sure we have a valid URL for Referer. if "" in (referer.scheme, referer.netloc): return self._reject(request, REASON_MALFORMED_REFERER) # Ensure that our Referer is also secure. if referer.scheme != "https" and not referer.netloc.endswith( ".onion"): return self._reject(request, REASON_INSECURE_REFERER) # If there isn't a CSRF_COOKIE_DOMAIN, require an exact match # match on host:port. If not, obey the cookie rules (or those # for the session cookie, if CSRF_USE_SESSIONS). good_referer = (settings.SESSION_COOKIE_DOMAIN if settings.CSRF_USE_SESSIONS else settings.CSRF_COOKIE_DOMAIN) if good_referer is not None: server_port = request.get_port() if server_port not in ("443", "80"): good_referer = "%s:%s" % (good_referer, server_port) else: try: # request.get_host() includes the port. good_referer = request.get_host() except DisallowedHost: pass # Create a list of all acceptable HTTP referers, including the # current host if it's permitted by ALLOWED_HOSTS. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) if good_referer is not None: good_hosts.append(good_referer) if not any( is_same_domain(referer.netloc, host) for host in good_hosts): reason = REASON_BAD_REFERER % referer.geturl() return self._reject(request, reason) csrf_token = self._get_token(request) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": try: request_csrf_token = request.POST.get( "csrfmiddlewaretoken", "") except OSError: # 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, # and possible for PUT/DELETE. request_csrf_token = request.META.get( settings.CSRF_HEADER_NAME, "") request_csrf_token = _sanitize_token(request_csrf_token) if not _compare_masked_tokens(request_csrf_token, csrf_token): return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC7231 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # secret we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = request.META.get('HTTP_REFERER') # -- Change from original here -- # # Only checks referer if it is present. # It's not a failure condition if the referer is not present. # Our site is HTTPS-only which does not need to rely on # referer checking. Above example does not apply. if referer is not None: referer = urlparse(referer) # Make sure we have a valid URL for Referer. if '' in (referer.scheme, referer.netloc): return self._reject(request, REASON_MALFORMED_REFERER) # Ensure that our Referer is also secure. if referer.scheme != 'https': return self._reject(request, REASON_INSECURE_REFERER) # If there isn't a CSRF_COOKIE_DOMAIN, require an exact match # match on host:port. If not, obey the cookie rules (or those # for the session cookie, if CSRF_USE_SESSIONS). good_referer = ( settings.SESSION_COOKIE_DOMAIN if settings.CSRF_USE_SESSIONS else settings.CSRF_COOKIE_DOMAIN ) if good_referer is not None: server_port = request.get_port() if server_port not in ('443', '80'): good_referer = '%s:%s' % (good_referer, server_port) else: try: # request.get_host() includes the port. good_referer = request.get_host() except DisallowedHost: pass # Create a list of all acceptable HTTP referers, including the # current host if it's permitted by ALLOWED_HOSTS. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) if good_referer is not None: good_hosts.append(good_referer) if not any(is_same_domain(referer.netloc, host) for host in good_hosts): reason = REASON_BAD_REFERER % referer.geturl() return self._reject(request, reason) csrf_token = request.META.get('CSRF_COOKIE') if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": 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, # and possible for PUT/DELETE. request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '') request_csrf_token = _sanitize_token(request_csrf_token) if not _compare_salted_tokens(request_csrf_token, csrf_token): return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME] except KeyError: csrf_token = None else: csrf_token = _sanitize_token(cookie_token) if csrf_token != cookie_token: # Cookie token needed to be replaced; # the cookie needs to be reset. request.csrf_cookie_needs_reset = True # Use same token next time. request.META['CSRF_COOKIE'] = csrf_token # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC7231 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # secret we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = force_text(request.META.get('HTTP_REFERER'), strings_only=True, errors='replace') if referer is not None: referer = urlparse(referer) # Make sure we have a valid URL for Referer. if '' in (referer.scheme, referer.netloc): return self._reject(request, REASON_MALFORMED_REFERER) # Ensure that our Referer is also secure. if referer.scheme != 'https': return self._reject(request, REASON_INSECURE_REFERER) # If there isn't a CSRF_COOKIE_DOMAIN, assume we need an exact # match on host:port. If not, obey the cookie rules. if settings.CSRF_COOKIE_DOMAIN is None: # request.get_host() includes the port. good_referer = request.get_host() else: good_referer = settings.CSRF_COOKIE_DOMAIN server_port = request.get_port() if server_port not in ('443', '80'): good_referer = '%s:%s' % (good_referer, server_port) # Here we generate a list of all acceptable HTTP referers, # including the current host since that has been validated # upstream. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) good_hosts.append(good_referer) if not any( is_same_domain(referer.netloc, host) for host in good_hosts): reason = REASON_BAD_REFERER % referer.geturl() return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": 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, # and possible for PUT/DELETE. request_csrf_token = request.META.get( settings.CSRF_HEADER_NAME, '') request_csrf_token = _sanitize_token(request_csrf_token) if not _compare_salted_tokens(request_csrf_token, csrf_token): return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: csrf_token = _sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME]) # Use same token next time request.META['CSRF_COOKIE'] = csrf_token except KeyError: csrf_token = None # Generate token and store it in the request, so it's # available to the view. request.META["CSRF_COOKIE"] = _get_new_csrf_key() # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC2616 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # nonce we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = request.META.get('HTTP_REFERER') if referer is None: logger.warning('Forbidden (%s): %s', REASON_NO_REFERER, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_REFERER) # Note that request.get_host() includes the port. good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) logger.warning('Forbidden (%s): %s', reason, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. logger.warning('Forbidden (%s): %s', REASON_NO_CSRF_COOKIE, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') if request_csrf_token == "": # Fall back to X-CSRFToken, to make things easier for AJAX, # and possible for PUT/DELETE. request_csrf_token = request.META.get('HTTP_X_XSRF_TOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): logger.warning('Forbidden (%s): %s', REASON_BAD_TOKEN, request.path, extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: csrf_token = _sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME]) # Use same token next time request.META['CSRF_COOKIE'] = csrf_token except KeyError: csrf_token = None # Generate token and store it in the request, so it's # available to the view. request.META["CSRF_COOKIE"] = _get_new_csrf_key() # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, 'csrf_exempt', False): return None # Assume that anything not defined as 'safe' by RFC2616 needs protection if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'): if getattr(request, '_dont_enforce_csrf_checks', False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. logger.warning('Forbidden (%s): %s', REASON_NO_CSRF_COOKIE, request.path, extra={ 'status_code': 403, 'request': request, }) return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": request_csrf_token = request.POST.get('csrfmiddlewaretoken', '') if request_csrf_token == "": # Fall back to X-CSRFToken, to make things easier for AJAX, # and possible for PUT/DELETE. request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): logger.warning('Forbidden (%s): %s', REASON_BAD_TOKEN, request.path, extra={ 'status_code': 403, 'request': request, }) return self._reject(request, REASON_BAD_TOKEN) resp = self._accept(request) request.META["CSRF_COOKIE_USED"] = True return resp
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: request.META["CSRF_COOKIE"] = _sanitize_token( request.COOKIES[settings.CSRF_COOKIE_NAME]) cookie_is_new = False except KeyError: request.META["CSRF_COOKIE"] = _get_new_csrf_key() cookie_is_new = True if getattr(callback, 'csrf_exempt', False): return None if request.method == 'POST': if getattr(request, '_dont_enforce_csrf_checks', False): return self._accept(request) # let initial signed requests pass if 'signed_request' in request.POST: post = request.POST.copy() post.pop('signed_request') if len(post) == 0: return self._accept(request) if request.is_secure() and getattr(settings, 'HTTPS_REFERER_REQUIRED', True): referer = request.META.get('HTTP_REFERER') if referer is None: logger.warning('Forbidden (%s): %s' % (REASON_NO_REFERER, request.path), extra={ 'status_code': 403, 'request': request, }) return self._reject(request, REASON_NO_REFERER) # Note that request.get_host() includes the port good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) logger.warning('Forbidden (%s): %s' % (reason, request.path), extra={ 'status_code': 403, 'request': request, }) return self._reject(request, reason) if cookie_is_new: try: session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] csrf_token = _make_legacy_session_token(session_id) except KeyError: logger.warning('Forbidden (%s): %s' % (REASON_NO_COOKIE, request.path), extra={ 'status_code': 403, 'request': request, }) return self._reject(request, REASON_NO_COOKIE) else: csrf_token = request.META["CSRF_COOKIE"] # check incoming token request_csrf_token = request.POST.get('csrfmiddlewaretoken', None) if not request_csrf_token: request_csrf_token = request.POST.get('state', '') if request_csrf_token == "": # Fall back to X-CSRFToken, to make things easier for AJAX request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): if cookie_is_new: # probably a problem setting the CSRF cookie logger.warning('Forbidden (%s): %s' % (REASON_NO_CSRF_COOKIE, request.path), extra={ 'status_code': 403, 'request': request, }) return self._reject(request, REASON_NO_CSRF_COOKIE) else: logger.warning('Forbidden (%s): %s' % (REASON_BAD_TOKEN, request.path), extra={ 'status_code': 403, 'request': request, }) return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, 'csrf_processing_done', False): return None try: request.META["CSRF_COOKIE"] = _sanitize_token(request.COOKIES[settings.CSRF_COOKIE_NAME]) cookie_is_new = False except KeyError: request.META["CSRF_COOKIE"] = _get_new_csrf_key() cookie_is_new = True if getattr(callback, 'csrf_exempt', False): return None if request.method == 'POST': if getattr(request, '_dont_enforce_csrf_checks', False): return self._accept(request) if request.is_secure() and getattr(settings, 'HTTPS_REFERER_REQUIRED', True): referer = request.META.get('HTTP_REFERER') if referer is None : logger.warning('Forbidden (%s): %s' % (REASON_NO_REFERER, request.path), extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_REFERER) # Note that request.get_host() includes the port good_referer = 'https://%s/' % request.get_host() if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) logger.warning('Forbidden (%s): %s' % (reason, request.path), extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, reason) if cookie_is_new: try: session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] csrf_token = _make_legacy_session_token(session_id) except KeyError: logger.warning('Forbidden (%s): %s' % (REASON_NO_COOKIE, request.path), extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_COOKIE) else: csrf_token = request.META["CSRF_COOKIE"] # check incoming token request_csrf_token = request.POST.get('csrfmiddlewaretoken', None) if not request_csrf_token: request_csrf_token = request.POST.get('state', '') if request_csrf_token == "": # Fall back to X-CSRFToken, to make things easier for AJAX request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '') if not constant_time_compare(request_csrf_token, csrf_token): if cookie_is_new: # probably a problem setting the CSRF cookie logger.warning('Forbidden (%s): %s' % (REASON_NO_CSRF_COOKIE, request.path), extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_NO_CSRF_COOKIE) else: logger.warning('Forbidden (%s): %s' % (REASON_BAD_TOKEN, request.path), extra={ 'status_code': 403, 'request': request, } ) return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)
def process_view(self, request, callback, callback_args, callback_kwargs): if getattr(request, "csrf_processing_done", False): return None try: cookie_token = request.COOKIES[settings.CSRF_COOKIE_NAME] except KeyError: csrf_token = None else: csrf_token = _sanitize_token(cookie_token) if csrf_token != cookie_token: # Cookie token needed to be replaced; # the cookie needs to be reset. request.csrf_cookie_needs_reset = True # Use same token next time. request.META["CSRF_COOKIE"] = csrf_token # Wait until request.META["CSRF_COOKIE"] has been manipulated before # bailing out, so that get_token still works if getattr(callback, "csrf_exempt", False): return None # Assume that anything not defined as 'safe' by RFC7231 needs protection if request.method not in ("GET", "HEAD", "OPTIONS", "TRACE"): if getattr(request, "_dont_enforce_csrf_checks", False): # Mechanism to turn off CSRF checks for test suite. # It comes after the creation of CSRF cookies, so that # everything else continues to work exactly the same # (e.g. cookies are sent, etc.), but before any # branches that call reject(). return self._accept(request) if request.is_secure(): # Suppose user visits http://example.com/ # An active network attacker (man-in-the-middle, MITM) sends a # POST form that targets https://example.com/detonate-bomb/ and # submits it via JavaScript. # # The attacker will need to provide a CSRF cookie and token, but # that's no problem for a MITM and the session-independent # secret we're using. So the MITM can circumvent the CSRF # protection. This is true for any HTTP connection, but anyone # using HTTPS expects better! For this reason, for # https://example.com/ we need additional protection that treats # http://example.com/ as completely untrusted. Under HTTPS, # Barth et al. found that the Referer header is missing for # same-domain requests in only about 0.2% of cases or less, so # we can use strict Referer checking. referer = force_text(request.META.get("HTTP_REFERER"), strings_only=True, errors="replace") if referer is not None: referer = urlparse(referer) # Make sure we have a valid URL for Referer. if "" in (referer.scheme, referer.netloc): return self._reject(request, REASON_MALFORMED_REFERER) # Ensure that our Referer is also secure. if referer.scheme != "https": return self._reject(request, REASON_INSECURE_REFERER) # If there isn't a CSRF_COOKIE_DOMAIN, assume we need an exact # match on host:port. If not, obey the cookie rules. if settings.CSRF_COOKIE_DOMAIN is None: # request.get_host() includes the port. good_referer = request.get_host() else: good_referer = settings.CSRF_COOKIE_DOMAIN server_port = request.get_port() if server_port not in ("443", "80"): good_referer = "%s:%s" % (good_referer, server_port) # Here we generate a list of all acceptable HTTP referers, # including the current host since that has been validated # upstream. good_hosts = list(settings.CSRF_TRUSTED_ORIGINS) good_hosts.append(good_referer) if not any(is_same_domain(referer.netloc, host) for host in good_hosts): reason = REASON_BAD_REFERER % referer.geturl() return self._reject(request, reason) if csrf_token is None: # No CSRF cookie. For POST requests, we insist on a CSRF cookie, # and in this way we can avoid all CSRF attacks, including login # CSRF. return self._reject(request, REASON_NO_CSRF_COOKIE) # Check non-cookie token for match. request_csrf_token = "" if request.method == "POST": 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, # and possible for PUT/DELETE. request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, "") request_csrf_token = _sanitize_token(request_csrf_token) if not _compare_salted_tokens(request_csrf_token, csrf_token): return self._reject(request, REASON_BAD_TOKEN) return self._accept(request)