======================= 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 `. For configuration instructions in a Django project, see the :ref:`Using CSP ` documentation. For an HTTP guide about CSP, see the `MDN Guide on CSP `_. .. _csp-overview: Overview ======== The `Content-Security-Policy specification `_ 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 `, 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 `_ 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 (``""``) 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`. Decorators ========== .. module:: django.views.decorators.csp Django provides decorators to control the Content Security Policy headers on a per-view basis. These allow overriding or disabling the enforced or report-only policy for specific views, providing fine-grained control when the global settings are not sufficient. Applying these overrides fully replaces the base CSP: they do not merge with existing rules. They can be used alongside the constants defined in :class:`~django.utils.csp.CSP`. .. warning:: Weakening or disabling a CSP policy on any page can compromise the security of the entire site. Because of the "same origin" policy, an attacker could exploit a vulnerability on one page to access other parts of the site. .. function:: csp_override(config)(view) Overrides the ``Content-Security-Policy`` header for the decorated view using directives in the same format as the :setting:`SECURE_CSP` setting. The ``config`` argument must be a mapping with the desired CSP directives. If ``config`` is an empty mapping (``{}``), no CSP enforcement header will be added to the response returned by that view, effectively disabling CSP for that view. Examples:: from django.http import HttpResponse from django.utils.csp import CSP from django.views.decorators.csp import csp_override @csp_override( { "default-src": [CSP.SELF], "img-src": [CSP.SELF, "data:"], } ) def my_view(request): return HttpResponse("Custom Content-Security-Policy header applied") @csp_override({}) def my_other_view(request): return HttpResponse("No Content-Security-Policy header added") .. function:: csp_report_only_override(config)(view) Overrides the ``Content-Security-Policy-Report-Only`` header for the decorated view using directives in the same format as the :setting:`SECURE_CSP_REPORT_ONLY` setting. Like :func:`csp_override`, the ``config`` argument must be a mapping with the desired CSP directives. If ``config`` is an empty mapping (``{}``), no CSP report-only header will be added to the response returned by that view, effectively disabling report-only CSP for that view. Examples:: from django.http import HttpResponse from django.utils.csp import CSP from django.views.decorators.csp import csp_report_only_override @csp_report_only_override( { "default-src": [CSP.SELF], "img-src": [CSP.SELF, "data:"], "report-uri": "https://mysite.com/csp-report/", } ) def my_view(request): return HttpResponse("Custom Content-Security-Policy-Report-Only header applied") @csp_report_only_override({}) def my_other_view(request): return HttpResponse("No Content-Security-Policy-Report-Only header added") The examples above assume function-based views. For class-based views, see the :ref:`guide for decorating class-based views `. .. _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 ``