============================== Content Security Policy ============================== To implement content security policy in our django application, we make use of the django-csp package This package adds middleware to our application that handles trusted sources of external data, like scripts, styles, images and fonts The main settings for this can be found in settings.py Overriding CSP settings per view ================================ ``@csp_exempt`` =============== Using the ``@csp_exempt`` decorator disables the CSP header on a given view. .. code-block:: python from csp.decorators import csp_exempt # Will not have a CSP header. @csp_exempt() def myview(request): return render(...) # Will not have a CSP report-only header. @csp_exempt(REPORT_ONLY=True) def myview(request): return render(...) You can manually set this on a per-response basis by setting the ``_csp_exempt`` or ``_csp_exempt_ro`` attribute on the response to ``True``: .. code-block:: python # Also will not have a CSP header. def myview(request): response = render(...) response._csp_exempt = True return response ``@csp_update`` =============== The ``@csp_update`` header allows you to **append** values to the source lists specified in the settings. If there is no setting, the value passed to the decorator will be used verbatim. .. note:: To quote the CSP spec: "There's no inheritance; ... the default list is not used for that resource type" if it is set. E.g., the following will not allow images from 'self': default-src 'self'; img-src imgsrv.com The decorator expects a single dictionary argument, where the keys are the directives and the values are either strings, lists or tuples. An optional argument, ``REPORT_ONLY``, can be set to ``True`` to update the report-only policy instead of the enforced policy. .. code-block:: python from csp.decorators import csp_update # Will append imgsrv.com to the list of values for `img-src` in the enforced policy. @csp_update({"img-src": "imgsrv.com"}) def myview(request): return render(...) # Will append cdn-img.com to the list of values for `img-src` in the report-only policy. @csp_update({"img-src": "cdn-img.com"}, REPORT_ONLY=True) def myview(request): return render(...) ``@csp_replace`` ================ The ``@csp_replace`` decorator allows you to **replace** a source list specified in settings. If there is no setting, the value passed to the decorator will be used verbatim. (See the note under ``@csp_update``.) If the specified value is None, the corresponding key will not be included. The arguments and values are the same as ``@csp_update``: .. code-block:: python from csp.decorators import csp_replace # Will allow images only from imgsrv2.com in the enforced policy. @csp_replace({"img-src": "imgsrv2.com"}) def myview(request): return render(...) # Will allow images only from cdn-img2.com in the report-only policy. @csp_replace({"img-src": "cdn-img2.com"}, REPORT_ONLY=True) def myview(request): return render(...) The ``csp_replace`` decorator can also be used to remove a directive from the policy by setting the value to ``None``. For example, if the ``frame-ancestors`` directive is set in the Django settings and you want to remove the ``frame-ancestors`` directive from the policy for this view: .. code-block:: python from csp.decorators import csp_replace @csp_replace({"frame-ancestors": None}) def myview(request): return render(...) ``@csp`` ======== If you need to set the entire policy on a view, ignoring all the settings, you can use the ``@csp`` decorator. This can be stacked to update both the enforced policy and the report-only policy if both are in use, as shown below. .. code-block:: python from csp.constants import SELF, UNSAFE_INLINE from csp.decorators import csp @csp( { "default-src": [SELF], "img-src": ["imgsrv.com"], "script-src": ["scriptsrv.com", "googleanalytics.com", UNSAFE_INLINE], } ) @csp( { "default-src": [SELF], "img-src": ["imgsrv.com"], "script-src": ["scriptsrv.com", "googleanalytics.com"], "frame-src": [SELF], }, REPORT_ONLY=True, ) def myview(request): return render(...)