要在Django项目中启用内容安全策略(CSP):
将CSP中间件添加到 中间件 设置中:
MIDDLEWARE = [
# ...
"django.middleware.csp.ContentSecurityPolicyMiddleware",
# ...
]
在settings.py文件中,使用 SECURE_CSP 或 SECURE_CSP_REPORT_ONLY (或两者都使用)来配置CSP策略。CSP设置文档 提供了关于这两者之间差异的更多详细信息:
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,除了基本配置外,你还需要:
在CSP设置中包含 NONCE 占位符值。这仅适用于 script-src 或 style-src 指令:
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],
}
将 csp() 上下文处理器添加到你的 TEMPLATES 设置中。这样,生成的随机数就会作为``csp_nonce``上下文变量在 Django 模板中可用:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"OPTIONS": {
"context_processors": [
# ...
"django.template.context_processors.csp",
],
},
},
]
In your templates, add the nonce to elements that require it:
For inline <style> or <script> tags, use the csp_nonce context
variable directly:
<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 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 to each element, pass the object to the csp_nonce_attr tag:
{% csp_nonce_attr form.media %}
The csp_nonce_attr template tag was added, including support for
rendering Media objects.
缓存与Nonce复用
当模板中使用nonce时,ContentSecurityPolicyMiddleware 会自动处理生成唯一的nonce,并将相应的 nonce-<value> 源表达式插入到 Content-Security-Policy (或 Content-Security-Policy-Report-Only)头部中。
为确保行为正确,请确保HTML和头部(header)都在同一请求中生成,而不是从缓存中获取。有关实现细节和重要的缓存注意事项,请参阅 Nonce usage 的参考文档。
8月 05, 2026