Django
Django 6.0 brought CSP into core. Before that you needed django-csp; now the middleware, the settings and the template nonce all ship with the framework, and the report-only variant is a first-class setting rather than an afterthought.
What Django gives you
django.middleware.csp.ContentSecurityPolicyMiddleware, added toMIDDLEWARE.- Two mutually exclusive settings:
SECURE_CSPto enforce, andSECURE_CSP_REPORT_ONLYto report without blocking. - Policies written as a dictionary of directives, using constants from
django.utils.csprather than hand-assembled strings. CSP.NONCEinscript-srcorstyle-src, with the middleware generating a unique nonce per request.- The
django.template.context_processors.cspcontext processor, exposing{{ csp_nonce }}to templates.
Setting the header
Start in report-only mode. Your URL comes from the Setup page:
from django.utils.csp import CSP
SECURE_CSP_REPORT_ONLY = {
"default-src": [CSP.SELF],
"script-src": [CSP.SELF, CSP.NONCE],
"report-uri": "https://abc123.report-uri.com/r/d/csp/reportOnly",
}
MIDDLEWARE = [
"django.middleware.csp.ContentSecurityPolicyMiddleware",
# ...
]
When you are ready to enforce, move the same dictionary to SECURE_CSP and switch the endpoint to the enforce one so the two data sets stay separate in your account.
Adding a nonce
Register the context processor:
TEMPLATES = [{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"OPTIONS": {
"context_processors": [
"django.template.context_processors.csp",
],
},
}]
Then use it on any inline script or style:
<script nonce="{{ csp_nonce }}">
// allowed by the policy
</script>
Things to watch for
SECURE_CSPandSECURE_CSP_REPORT_ONLYare mutually exclusive. If you set both expecting a report-only shadow policy alongside an enforced one, you will not get it - run the report-only phase first, then switch.- Do not cache the HTML and the header together. A cached response serves a stale nonce to every visitor, which defeats the point entirely.
- On Django 5.2 and earlier there is no built-in support;
django-cspremains the route until you upgrade.
Official documentation
Django - How to use Django's Content Security Policy
Start Monitoring with Report URI
Already using us for CSP? Find your report-uri value on Setup, or view your CSP reports.
New to Report URI? Create an account and grab your report-uri value from the Setup page.