mirror of
https://github.com/django/django.git
synced 2025-10-06 05:19:09 +00:00
Lines in the docs files were manually adjusted to conform to the 79 columns limit per line (plus newline), improving readability and consistency across the content.
212 lines
8.4 KiB
Plaintext
212 lines
8.4 KiB
Plaintext
=======================
|
|
Content Security Policy
|
|
=======================
|
|
|
|
.. versionadded:: 6.0
|
|
|
|
.. module:: django.middleware.csp
|
|
:synopsis: Middleware for Content Security Policy headers
|
|
|
|
Content Security Policy (CSP) is a web security standard that helps prevent
|
|
content injection attacks by restricting the sources from which content can be
|
|
loaded. It plays an important role in a comprehensive :ref:`security strategy
|
|
<security-csp>`.
|
|
|
|
For configuration instructions in a Django project, see the :ref:`Using CSP
|
|
<csp-config>` documentation. For an HTTP guide about CSP, see the `MDN Guide on
|
|
CSP <https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP>`_.
|
|
|
|
.. _csp-overview:
|
|
|
|
Overview
|
|
========
|
|
|
|
The `Content-Security-Policy specification <https://www.w3.org/TR/CSP3/>`_
|
|
defines two complementary headers:
|
|
|
|
* ``Content-Security-Policy``: Enforces the CSP policy, blocking content that
|
|
violates the defined directives.
|
|
* ``Content-Security-Policy-Report-Only``: Reports CSP violations without
|
|
blocking content, allowing for non-intrusive testing.
|
|
|
|
Each policy is composed of one or more directives and their values, which
|
|
together instruct the browser on how to handle specific types of content.
|
|
|
|
When the :class:`~django.middleware.csp.ContentSecurityPolicyMiddleware` is
|
|
enabled, Django automatically builds and attaches the appropriate headers to
|
|
each response based on the configured :ref:`settings <csp-settings>`, unless
|
|
they have already been set by another layer.
|
|
|
|
.. _csp-settings:
|
|
|
|
Settings
|
|
========
|
|
|
|
The :class:`~django.middleware.csp.ContentSecurityPolicyMiddleware` is
|
|
configured using the following settings:
|
|
|
|
* :setting:`SECURE_CSP`: defines the **enforced Content Security Policy**.
|
|
* :setting:`SECURE_CSP_REPORT_ONLY`: defines a **report-only Content Security
|
|
Policy**.
|
|
|
|
.. admonition:: These settings can be used independently or together
|
|
|
|
* Use :setting:`SECURE_CSP` alone to enforce a policy that has already been
|
|
tested and verified.
|
|
* Use :setting:`SECURE_CSP_REPORT_ONLY` on its own to evaluate a new policy
|
|
without disrupting site behavior. This mode does not block violations, it
|
|
only logs them. It's useful for testing and monitoring, but provides no
|
|
protection against active threats.
|
|
* Use *both* to maintain an enforced baseline while experimenting with
|
|
changes. Even for well-established policies, continuing to collect reports
|
|
reports can help detect regressions, unexpected changes in behavior, or
|
|
potential tampering in production environments.
|
|
|
|
.. _csp-reports:
|
|
|
|
Policy violation reports
|
|
========================
|
|
|
|
When a CSP violation occurs, browsers typically log details to the developer
|
|
console, providing immediate feedback during development. To also receive these
|
|
reports programmatically, the policy must include a `reporting directive
|
|
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#reporting_directives>`_
|
|
such as ``report-uri`` that specifies where violation data should be sent.
|
|
|
|
Django supports configuring these directives via the
|
|
:setting:`SECURE_CSP_REPORT_ONLY` settings, but reports will only be issued by
|
|
the browser if the policy explicitly includes a valid reporting directive.
|
|
|
|
Django does not provide built-in functionality to receive, store, or process
|
|
violation reports. To collect and analyze them, you must implement your own
|
|
reporting endpoint or integrate with a third-party monitoring service.
|
|
|
|
.. _csp-constants:
|
|
|
|
CSP constants
|
|
=============
|
|
|
|
Django provides predefined constants representing common CSP source expression
|
|
keywords such as ``'self'``, ``'none'``, and ``'unsafe-inline'``. These
|
|
constants are intended for use in the directive values defined in the settings.
|
|
|
|
They are available through the :class:`~django.utils.csp.CSP` enum, and using
|
|
them is recommended over raw strings. This helps avoid common mistakes such as
|
|
typos, improper quoting, or inconsistent formatting, and ensures compliance
|
|
with the CSP specification.
|
|
|
|
.. module:: django.utils.csp
|
|
:synopsis: Constants for Content Security Policy
|
|
|
|
.. class:: CSP
|
|
|
|
Enum providing standardized constants for common CSP source expressions.
|
|
|
|
.. attribute:: NONE
|
|
|
|
Represents ``'none'``. Blocks loading resources for the given directive.
|
|
|
|
.. attribute:: REPORT_SAMPLE
|
|
|
|
Represents ``'report-sample'``. Instructs the browser to include a sample
|
|
of the violating code in reports. Note that this may expose sensitive
|
|
data.
|
|
|
|
.. attribute:: SELF
|
|
|
|
Represents ``'self'``. Allows loading resources from the same origin
|
|
(same scheme, host, and port).
|
|
|
|
.. attribute:: STRICT_DYNAMIC
|
|
|
|
Represents ``'strict-dynamic'``. Allows execution of scripts loaded by a
|
|
trusted script (e.g., one with a valid nonce or hash), without needing
|
|
``'unsafe-inline'``.
|
|
|
|
.. attribute:: UNSAFE_EVAL
|
|
|
|
Represents ``'unsafe-eval'``. Allows use of ``eval()`` and similar
|
|
JavaScript functions. Strongly discouraged.
|
|
|
|
.. attribute:: UNSAFE_HASHES
|
|
|
|
Represents ``'unsafe-hashes'``. Allows inline event handlers and some
|
|
``javascript:`` URIs when their content hashes match a policy rule.
|
|
Requires CSP Level 3+.
|
|
|
|
.. attribute:: UNSAFE_INLINE
|
|
|
|
Represents ``'unsafe-inline'``. Allows execution of inline scripts,
|
|
styles, and ``javascript:`` URLs. Generally discouraged, especially for
|
|
scripts.
|
|
|
|
.. attribute:: WASM_UNSAFE_EVAL
|
|
|
|
Represents ``'wasm-unsafe-eval'``. Permits compilation and execution of
|
|
WebAssembly code without enabling ``'unsafe-eval'`` for scripts.
|
|
|
|
.. attribute:: NONCE
|
|
|
|
Django-specific placeholder value (``"<CSP_NONCE_SENTINEL>"``) used in
|
|
``script-src`` or ``style-src`` directives to activate nonce-based CSP.
|
|
This string is replaced at runtime by the
|
|
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware` with a
|
|
secure, random nonce that is generated for each request. See detailed
|
|
explanation in :ref:`csp-nonce`.
|
|
|
|
.. _csp-nonce:
|
|
|
|
Nonce usage
|
|
===========
|
|
|
|
A CSP nonce ("number used once") is a unique, random value generated per HTTP
|
|
response. Django supports nonces as a secure way to allow specific inline
|
|
``<script>`` or ``<style>`` elements to execute without relying on
|
|
``'unsafe-inline'``.
|
|
|
|
Nonces are enabled by including the special placeholder
|
|
:attr:`~django.utils.csp.CSP.NONCE` in the relevant directive(s) of your
|
|
:ref:`CSP settings <csp-settings>`, such as ``script-src`` or ``style-src``.
|
|
When present, the
|
|
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`
|
|
will generate a nonce and insert the corresponding ``nonce-<value>`` source
|
|
expression into the CSP header.
|
|
|
|
To use this nonce in templates, the
|
|
:func:`~django.template.context_processors.csp` context processor needs to be
|
|
enabled. It adds a ``csp_nonce`` variable to the template context, allowing
|
|
inline elements to include a matching ``nonce={{ csp_nonce }}`` attribute in
|
|
inline scripts or styles.
|
|
|
|
The browser will only execute inline elements that include a ``nonce=<value>``
|
|
attribute matching the one specified in the ``Content-Security-Policy`` (or
|
|
``Content-Security-Policy-Report-Only``) header. This mechanism provides
|
|
fine-grained control over which inline code is allowed to run.
|
|
|
|
If a template includes ``{{ csp_nonce }}`` but the policy does not include
|
|
:attr:`~django.utils.csp.CSP.NONCE`, the HTML will include a nonce attribute,
|
|
but the header will lack the required source expression. In this case, the
|
|
browser will block the inline script or style (or report it for report-only
|
|
configurations).
|
|
|
|
Nonce generation and caching
|
|
----------------------------
|
|
|
|
Django's nonce generation is **lazy**: the middleware only generates a nonce if
|
|
``{{ csp_nonce }}`` is accessed during template rendering. This avoids
|
|
unnecessary work for pages that do not use nonces.
|
|
|
|
However, because nonces must be unique per request, extra care is needed when
|
|
using full-page caching (e.g., Django's cache middleware, CDN caching). Serving
|
|
cached responses with previously generated nonces may result in reuse across
|
|
users and requests. Although such responses may still appear to work (since the
|
|
nonce in the CSP header and HTML content match), reuse defeats the purpose of
|
|
the nonce and weakens security.
|
|
|
|
To ensure nonce-based policies remain effective:
|
|
|
|
* Avoid caching full responses that include ``{{ csp_nonce }}``.
|
|
* If caching is necessary, use a strategy that injects a fresh nonce on each
|
|
request, or consider refactoring your application to avoid inline scripts and
|
|
styles altogether.
|