mirror of
https://github.com/pretix/pretix.git
synced 2026-08-06 10:07:50 +00:00
Handle safe types centrally
This commit is contained in:
@@ -266,6 +266,22 @@ def _merge_csp(a, b):
|
||||
|
||||
|
||||
class SecurityMiddleware(MiddlewareMixin):
|
||||
SAFE_TYPES = (
|
||||
# CSP policies are only used for:
|
||||
# - HTML and SVG in top-level contexts
|
||||
# - SVG or JS Workers delivered in embedded contexts
|
||||
# See: https://www.w3.org/TR/CSP2/#which-policy-applies
|
||||
# Therefore, we can save bandwidth on not including our (sometimes huge) policy
|
||||
# on API responses or CSS. We do however include it with other types as a precaution
|
||||
# (whitelist instead of blacklist) and we also do not whitelist JavaScript in
|
||||
# we ever add service workers to not break the protection of this feature:
|
||||
# https://www.w3.org/TR/CSP2/#sandboxing-and-workers
|
||||
'application/json',
|
||||
'text/css',
|
||||
# We used to skip CSP for PDF since it was necessary for inline previews in Safari,
|
||||
# but at the moment it does not seem to be an issue to just send it.
|
||||
)
|
||||
|
||||
def process_response(self, request, resp):
|
||||
if settings.DEBUG and resp.status_code >= 400:
|
||||
# Don't use CSP on debug error page as it breaks of Django's fancy error
|
||||
@@ -277,6 +293,11 @@ class SecurityMiddleware(MiddlewareMixin):
|
||||
# https://github.com/pretix/pretix/issues/765
|
||||
resp['P3P'] = 'CP=\"ALL DSP COR CUR ADM TAI OUR IND COM NAV INT\"'
|
||||
|
||||
if "Content-Type" in resp and resp["Content-Type"].split(";")[0] in self.SAFE_TYPES:
|
||||
if 'Content-Security-Policy' in resp:
|
||||
del resp['Content-Security-Policy']
|
||||
return resp
|
||||
|
||||
if not getattr(resp, '_csp_ignore', False):
|
||||
resp['Content-Security-Policy'] = _render_csp(self._build_csp(request, resp))
|
||||
elif 'Content-Security-Policy' in resp:
|
||||
|
||||
@@ -70,7 +70,6 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
|
||||
if 'placeholders' in request.GET:
|
||||
return self.get_placeholders_help(request)
|
||||
resp = super().get(request, *args, **kwargs)
|
||||
resp._csp_ignore = True
|
||||
return resp
|
||||
|
||||
def get_placeholders_help(self, request):
|
||||
|
||||
@@ -162,7 +162,6 @@ class XHRView(View):
|
||||
|
||||
paypal_order = prov._create_paypal_order(request, None, cart_total)
|
||||
r = JsonResponse(paypal_order.dict() if paypal_order else {})
|
||||
r._csp_ignore = True
|
||||
return r
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ def theme_css(request, **kwargs):
|
||||
obj = getattr(request, "event", request.organizer)
|
||||
css = get_theme_vars_css(obj, widget=False)
|
||||
resp = HttpResponse(css, content_type="text/css")
|
||||
resp._csp_ignore = True
|
||||
resp["Access-Control-Allow-Origin"] = "*"
|
||||
if "version" in request.GET:
|
||||
resp["Expires"] = http_date(time.time() + 3600 * 24 * 30)
|
||||
|
||||
@@ -164,7 +164,6 @@ def widget_css(request, version, **kwargs):
|
||||
css = f"/* v{version} */\n" + theme_css + widget_css
|
||||
|
||||
resp = FileResponse(css, content_type='text/css')
|
||||
resp._csp_ignore = True
|
||||
resp['Access-Control-Allow-Origin'] = '*'
|
||||
return resp
|
||||
|
||||
@@ -246,7 +245,6 @@ def widget_js(request, version, lang, **kwargs):
|
||||
cached_js = cache.get(cache_prefix)
|
||||
if cached_js and not settings.DEBUG:
|
||||
resp = HttpResponse(cached_js, content_type='text/javascript')
|
||||
resp._csp_ignore = True
|
||||
resp['Access-Control-Allow-Origin'] = '*'
|
||||
return resp
|
||||
|
||||
@@ -278,7 +276,6 @@ def widget_js(request, version, lang, **kwargs):
|
||||
gs.settings.set(checksum_key, checksum)
|
||||
cache.set(cache_prefix, data, 3600 * 4)
|
||||
resp = HttpResponse(data, content_type='text/javascript')
|
||||
resp._csp_ignore = True
|
||||
resp['Access-Control-Allow-Origin'] = '*'
|
||||
return resp
|
||||
|
||||
@@ -414,7 +411,6 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
self.post_process(data)
|
||||
resp = JsonResponse(data)
|
||||
resp['Access-Control-Allow-Origin'] = '*'
|
||||
resp._csp_ignore = True
|
||||
return resp
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user