forked from CGM_Public/pretix_original
Fix customer views using wrong csrf middleware (#6027)
* Fix customer views using wrong csrf middleware This lead to persistent csrf validation errors if the token from the cookie expired, which could only be solved by clearing cookies. * Remove unneccesary csrf_protect decorators * Fix typo Co-authored-by: Raphael Michel <michel@pretix.eu> --------- Co-authored-by: Raphael Michel <michel@pretix.eu>
This commit is contained in:
@@ -27,11 +27,11 @@ from django.template import TemplateDoesNotExist, loader
|
||||
from django.template.loader import get_template
|
||||
from django.utils.functional import Promise
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.decorators.csrf import requires_csrf_token
|
||||
from sentry_sdk import last_event_id
|
||||
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.middleware import get_language_from_request
|
||||
from pretix.multidomain.middlewares import requires_csrf_token
|
||||
|
||||
|
||||
def csrf_failure(request, reason=""):
|
||||
|
||||
@@ -50,6 +50,7 @@ from django.middleware.csrf import (
|
||||
from django.shortcuts import render
|
||||
from django.urls import set_urlconf
|
||||
from django.utils.cache import patch_vary_headers
|
||||
from django.utils.decorators import decorator_from_middleware
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.utils.http import http_date
|
||||
from django_scopes import scopes_disabled
|
||||
@@ -270,26 +271,50 @@ class CsrfViewMiddleware(BaseCsrfMiddleware):
|
||||
if request.session.get(CSRF_SESSION_KEY) != request.META["CSRF_COOKIE"]:
|
||||
request.session[CSRF_SESSION_KEY] = request.META["CSRF_COOKIE"]
|
||||
else:
|
||||
is_secure = request.scheme == 'https'
|
||||
# Set the CSRF cookie even if it's already set, so we renew
|
||||
# the expiry timer.
|
||||
if is_secure and settings.CSRF_COOKIE_NAME in request.COOKIES: # remove legacy cookie
|
||||
if request.is_secure() and settings.CSRF_COOKIE_NAME in request.COOKIES: # remove legacy cookie
|
||||
# response.delete_cookie does not work as we might have set a partitioned cookie
|
||||
delete_cookie_without_samesite(
|
||||
request, response,
|
||||
settings.CSRF_COOKIE_NAME,
|
||||
path=settings.CSRF_COOKIE_PATH,
|
||||
secure=is_secure,
|
||||
secure=request.is_secure(),
|
||||
httponly=settings.CSRF_COOKIE_HTTPONLY
|
||||
)
|
||||
set_cookie_without_samesite(
|
||||
request, response,
|
||||
'__Host-' + settings.CSRF_COOKIE_NAME if is_secure else settings.CSRF_COOKIE_NAME,
|
||||
'__Host-' + settings.CSRF_COOKIE_NAME if request.is_secure() else settings.CSRF_COOKIE_NAME,
|
||||
request.META["CSRF_COOKIE"],
|
||||
max_age=settings.CSRF_COOKIE_AGE,
|
||||
path=settings.CSRF_COOKIE_PATH,
|
||||
secure=is_secure,
|
||||
secure=request.is_secure(),
|
||||
httponly=settings.CSRF_COOKIE_HTTPONLY
|
||||
)
|
||||
# Content varies with the CSRF cookie, so set the Vary header.
|
||||
patch_vary_headers(response, ('Cookie',))
|
||||
|
||||
def process_response(self, request, response):
|
||||
if (
|
||||
not settings.CSRF_USE_SESSIONS
|
||||
and request.is_secure()
|
||||
and settings.CSRF_COOKIE_NAME in response.cookies
|
||||
and response.cookies[settings.CSRF_COOKIE_NAME].value
|
||||
):
|
||||
raise ValueError("Usage of djangos CsrfViewMiddleware detected (legacy cookie found in response). "
|
||||
"This may be caused by using csrf_project or requires_csrf_token from django.views.decorators.csrf. "
|
||||
"Use the pretix.multidomain.middlewares equivalent instead.")
|
||||
|
||||
return super().process_response(request, response)
|
||||
|
||||
|
||||
csrf_protect = decorator_from_middleware(CsrfViewMiddleware)
|
||||
|
||||
|
||||
class _EnsureCsrfToken(CsrfViewMiddleware):
|
||||
# Behave like CsrfViewMiddleware but don't reject requests or log warnings.
|
||||
def _reject(self, request, reason):
|
||||
return None
|
||||
|
||||
|
||||
requires_csrf_token = decorator_from_middleware(_EnsureCsrfToken)
|
||||
|
||||
@@ -42,7 +42,6 @@ from django.utils.functional import cached_property
|
||||
from django.utils.http import url_has_allowed_host_and_scheme
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.decorators.cache import never_cache
|
||||
from django.views.decorators.csrf import csrf_protect
|
||||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
from django.views.generic import FormView, ListView, View
|
||||
|
||||
@@ -99,7 +98,6 @@ class LoginView(RedirectBackMixin, FormView):
|
||||
redirect_authenticated_user = True
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -211,7 +209,6 @@ class RegistrationView(RedirectBackMixin, FormView):
|
||||
redirect_authenticated_user = True
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -255,7 +252,6 @@ class SetPasswordView(FormView):
|
||||
template_name = 'pretixpresale/organizers/customer_setpassword.html'
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -299,7 +295,6 @@ class ResetPasswordView(FormView):
|
||||
template_name = 'pretixpresale/organizers/customer_resetpw.html'
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -523,7 +518,6 @@ class ChangePasswordView(CustomerAccountBaseMixin, FormView):
|
||||
form_class = ChangePasswordForm
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -557,7 +551,6 @@ class ChangeInformationView(CustomerAccountBaseMixin, FormView):
|
||||
form_class = ChangeInfoForm
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -665,7 +658,6 @@ class SSOLoginView(RedirectBackMixin, View):
|
||||
redirect_authenticated_user = True
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
@@ -728,7 +720,6 @@ class SSOLoginReturnView(RedirectBackMixin, View):
|
||||
redirect_authenticated_user = True
|
||||
|
||||
@method_decorator(sensitive_post_parameters())
|
||||
@method_decorator(csrf_protect)
|
||||
@method_decorator(never_cache)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.organizer.settings.customer_accounts:
|
||||
|
||||
Reference in New Issue
Block a user