diff --git a/doc/admin/config.rst b/doc/admin/config.rst index ed4b4748dc..75adf720a4 100644 --- a/doc/admin/config.rst +++ b/doc/admin/config.rst @@ -29,6 +29,7 @@ Example:: currency=EUR datadir=/data plugins_default=pretix.plugins.sendmail,pretix.plugins.statistics + cookie_domain=.pretix.de ``instance_name`` The name of this installation. Default: ``pretix.de`` @@ -47,6 +48,9 @@ Example:: A comma-separated list of plugins that are enabled by default for all new events. Defaults to ``pretix.plugins.sendmail,pretix.plugins.statistics``. +``cookie_domain`` + The cookie domain to be set. Defaults to ``None``. + Locale settings --------------- diff --git a/src/pretix/multidomain/middlewares.py b/src/pretix/multidomain/middlewares.py index 7d34b99bc5..df43f1097c 100644 --- a/src/pretix/multidomain/middlewares.py +++ b/src/pretix/multidomain/middlewares.py @@ -13,6 +13,8 @@ from django.utils.http import cookie_date from pretix.multidomain.models import KnownDomain +LOCAL_HOST_NAMES = ('testserver', 'localhost') + class MultiDomainMiddleware: def process_request(self, request): @@ -37,7 +39,7 @@ class MultiDomainMiddleware: kd = KnownDomain.objects.get(domainname=domain) # noqa request.domain = kd except: - if settings.DEBUG or domain in ('testserver', 'localhost') or domain == default_domain: + if settings.DEBUG or domain in LOCAL_HOST_NAMES or domain == default_domain: request.urlconf = "pretix.multidomain.maindomain_urlconf" else: raise DisallowedHost("Unknown host: %r" % host) @@ -87,7 +89,8 @@ class SessionMiddleware(BaseSessionMiddleware): request.session.save() response.set_cookie(settings.SESSION_COOKIE_NAME, request.session.session_key, max_age=max_age, - expires=expires, domain=request.host, + expires=expires, + domain=get_cookie_domain(request), path=settings.SESSION_COOKIE_PATH, secure=request.scheme == 'https', httponly=settings.SESSION_COOKIE_HTTPONLY or None) @@ -113,7 +116,7 @@ class CsrfViewMiddleware(BaseCsrfMiddleware): response.set_cookie(settings.CSRF_COOKIE_NAME, request.META["CSRF_COOKIE"], max_age=settings.CSRF_COOKIE_AGE, - domain=request.host, + domain=get_cookie_domain(request), path=settings.CSRF_COOKIE_PATH, secure=request.scheme == 'https', httponly=settings.CSRF_COOKIE_HTTPONLY @@ -122,3 +125,19 @@ class CsrfViewMiddleware(BaseCsrfMiddleware): patch_vary_headers(response, ('Cookie',)) response.csrf_processing_done = True return response + + +def get_cookie_domain(request): + if '.' not in request.host: + # As per spec, browsers do not accept cookie domains without dots in it, + # e.g. "localhost", see http://curl.haxx.se/rfc/cookie_spec.html + return None + default_domain, default_port = split_domain_port(urlparse(settings.SITE_URL).netloc) + if request.host == default_domain: + # We are on our main domain, set the cookie domain the user has chosen + return settings.SESSION_COOKIE_DOMAIN + else: + # We are on an organizer's custom domain, set no cookie domain, as we do not want + # the cookies to be present on any other domain. Setting an explicit value can be + # dangerous, see http://erik.io/blog/2014/03/04/definitive-guide-to-cookie-domains/ + return None diff --git a/src/pretix/settings.py b/src/pretix/settings.py index d952f14631..3666be2db7 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -118,6 +118,8 @@ if HAS_CELERY: CELERY_RESULT_BACKEND = config.get('celery', 'backend') CELERY_SEND_TASK_ERROR_EMAILS = bool(ADMINS) +SESSION_COOKIE_DOMAIN = config.get('pretix', 'cookie_domain', fallback=None) + # Internal settings STATIC_ROOT = '_static'