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): # 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 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 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): """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 compare_sanitized_tokens(request_csrf_token, csrf_token): return constant_time_compare( _unsalt_cipher_token(request_csrf_token), _unsalt_cipher_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 = _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)