summaryrefslogtreecommitdiff
path: root/docs/howto/csp.txt
blob: f37bb2a82ad934b2cb21c105bed82c476b43d72b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
===========================================
How to use Django's Content Security Policy
===========================================

.. _csp-config:

Basic config
============

To enable Content Security Policy (CSP) in your Django project:

1. Add the CSP middleware to your :setting:`MIDDLEWARE` setting::

    MIDDLEWARE = [
        # ...
        "django.middleware.csp.ContentSecurityPolicyMiddleware",
        # ...
    ]

2. Configure the CSP policies in your ``settings.py`` using either
   :setting:`SECURE_CSP` or :setting:`SECURE_CSP_REPORT_ONLY` (or both). The
   :ref:`CSP Settings docs <csp-settings>` provide more details about the
   differences between these two::

    from django.utils.csp import CSP

    # To enforce a CSP policy:
    SECURE_CSP = {
        "default-src": [CSP.SELF],
        # Add more directives to be enforced.
    }

    # Or for report-only mode:
    SECURE_CSP_REPORT_ONLY = {
        "default-src": [CSP.SELF],
        # Add more directives as needed.
        "report-uri": "/path/to/reports-endpoint/",
    }

.. _csp-nonce-config:

Nonce config
============

To use nonces in your CSP policy, beside the basic config, you need to:

1. Include the :attr:`~django.utils.csp.CSP.NONCE` placeholder value in the CSP
   settings. This only applies to ``script-src`` or ``style-src`` directives::

    from django.utils.csp import CSP

    SECURE_CSP = {
        "default-src": [CSP.SELF],
        # Allow self-hosted scripts and script tags with matching `nonce` attr.
        "script-src": [CSP.SELF, CSP.NONCE],
        # Example of the less secure 'unsafe-inline' option.
        "style-src": [CSP.SELF, CSP.UNSAFE_INLINE],
    }

2. Add the :func:`~django.template.context_processors.csp` context processor to
   your :setting:`TEMPLATES` setting. This makes the generated nonce value
   available in the Django templates as the ``csp_nonce`` context variable::

    TEMPLATES = [
        {
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            "OPTIONS": {
                "context_processors": [
                    # ...
                    "django.template.context_processors.csp",
                ],
            },
        },
    ]

3. In your templates, add the nonce to elements that require it:

   For inline ``<style>`` or ``<script>`` tags, use the ``csp_nonce`` context
   variable directly:

   .. code-block:: html+django

      <style nonce="{{ csp_nonce }}">
        /* These inline styles will be allowed. */
      </style>

      <script nonce="{{ csp_nonce }}">
        // This inline JavaScript will be allowed.
      </script>

   For external ``<script src="...">`` and ``<link rel="stylesheet">``
   elements, use the :ttag:`csp_nonce_attr` template tag:

   .. code-block:: html+django

      <script src="/path/to/script.js" {% csp_nonce_attr %}></script>
      <link rel="stylesheet" href="/path/to/style.css" {% csp_nonce_attr %}>

   To render a :class:`~django.forms.Media` object's assets with the nonce
   applied to each element, pass the object to the :ttag:`csp_nonce_attr` tag:

   .. code-block:: html+django

      {% csp_nonce_attr form.media %}

   .. versionchanged:: 6.1

       The :ttag:`csp_nonce_attr` template tag was added, including support for
       rendering :class:`~django.forms.Media` objects.

.. admonition:: Caching and Nonce Reuse

   The :class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`
   automatically handles generating a unique nonce and inserting the
   appropriate ``nonce-<value>`` source expression into the
   ``Content-Security-Policy`` (or ``Content-Security-Policy-Report-Only``)
   header when the nonce is used in a template.

   To ensure correct behavior, make sure both the HTML and the header are
   generated within the same request and not served from cache. See the
   reference documentation on :ref:`csp-nonce` for implementation details and
   important caching considerations.