Content Security PolicyLink to this heading
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 security strategy.
For configuration instructions in a Django project, see the Using CSP documentation. For an HTTP guide about CSP, see the MDN Guide on CSP.
概况Link to this heading
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 ContentSecurityPolicyMiddleware is
enabled, Django automatically builds and attaches the appropriate headers to
each response based on the configured settings, unless
they have already been set by another layer.
配置Link to this heading
The ContentSecurityPolicyMiddleware is
configured using the following settings:
SECURE_CSP: defines the enforced Content Security Policy.SECURE_CSP_REPORT_ONLY: defines a report-only Content Security Policy.
Policy violation reportsLink to this heading
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
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 constantsLink to this heading
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 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.
- class CSPLink to this definition
Enum providing standardized constants for common CSP source expressions.
- NONELink to this definition
Represents
'none'. Blocks loading resources for the given directive.
- REPORT_SAMPLELink to this definition
Represents
'report-sample'. Instructs the browser to include a sample of the violating code in reports. Note that this may expose sensitive data.
- SELFLink to this definition
Represents
'self'. Allows loading resources from the same origin (same scheme, host, and port).
- STRICT_DYNAMICLink to this definition
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'.
- UNSAFE_EVALLink to this definition
Represents
'unsafe-eval'. Allows use ofeval()and similar JavaScript functions. Strongly discouraged.
- UNSAFE_HASHESLink to this definition
Represents
'unsafe-hashes'. Allows inline event handlers and somejavascript:URIs when their content hashes match a policy rule. Requires CSP Level 3+.
- UNSAFE_INLINELink to this definition
Represents
'unsafe-inline'. Allows execution of inline scripts, styles, andjavascript:URLs. Generally discouraged, especially for scripts.
- WASM_UNSAFE_EVALLink to this definition
Represents
'wasm-unsafe-eval'. Permits compilation and execution of WebAssembly code without enabling'unsafe-eval'for scripts.
- NONCELink to this definition
Django-specific placeholder value (
"<CSP_NONCE_SENTINEL>") used inscript-srcorstyle-srcdirectives to activate nonce-based CSP. This string is replaced at runtime by theContentSecurityPolicyMiddlewarewith a secure, random nonce that is generated for each request. See detailed explanation in Nonce usage.
装饰器Link to this heading
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 CSP.
- csp_override(config)(view)Link to this definition
Overrides the
Content-Security-Policyheader for the decorated view using directives in the same format as theSECURE_CSPsetting.The
configargument must be a mapping with the desired CSP directives. Ifconfigis an empty mapping ({}), no CSP enforcement header will be added to the response returned by that view, effectively disabling CSP for that view.举例:
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")
- csp_report_only_override(config)(view)Link to this definition
Overrides the
Content-Security-Policy-Report-Onlyheader for the decorated view using directives in the same format as theSECURE_CSP_REPORT_ONLYsetting.Like
csp_override(), theconfigargument must be a mapping with the desired CSP directives. Ifconfigis 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.举例:
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 guide for decorating class-based views.
Nonce usageLink to this heading
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
NONCE in the relevant directive(s) of your
CSP settings, such as script-src or style-src.
When present, the
ContentSecurityPolicyMiddleware
will generate a nonce and insert the corresponding nonce-<value> source
expression into the CSP header.
To use this nonce in templates, the
csp() context processor needs to be
enabled. It adds a csp_nonce variable to the template context.
For inline <script> and <style> elements, include the nonce directly
using the context variable:
<script nonce="{{ csp_nonce }}">
// This inline JavaScript will be allowed.
</script>
For external <script src="..."> and <link rel="stylesheet"> elements,
use the csp_nonce_attr template tag:
<script src="/path/to/script.js" {% csp_nonce_attr %}></script>
<link rel="stylesheet" href="/path/to/style.css" {% csp_nonce_attr %}>
To render a Media object's assets with the nonce
applied, pass the object to the csp_nonce_attr template tag:
{% csp_nonce_attr form.media %}
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 the CSP nonce but the policy does not include
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 cachingLink to this heading
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 }}orcsp_nonce_attr.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.