# Django 6.0.7 documentation

# 如何使用 Django 的内容安全策略

## 基础配置

要在Django项目中启用内容安全策略（CSP）：

1. 将CSP中间件添加到 `中间件` 设置中：

       MIDDLEWARE = [
           # ...
           "django.middleware.csp.ContentSecurityPolicyMiddleware",
           # ...
       ]

2. 在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/",
       }

## Nonce配置

要在CSP策略中使用一次性随机数，即Nonce，除了基本配置外，你还需要：

1. 在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],
       }

2. 将 `csp()` 上下文处理器添加到你的 `TEMPLATES` 设置中。这样，生成的随机数就会作为``csp_nonce``上下文变量在 Django 模板中可用：

       TEMPLATES = [
           {
               "BACKEND": "django.template.backends.django.DjangoTemplates",
               "OPTIONS": {
                   "context_processors": [
                       # ...
                       "django.template.context_processors.csp",
                   ],
               },
           },
       ]

3. 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 %}

   Changed in Django 6.1:

   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 的参考文档。