mirror of
https://github.com/django/django.git
synced 2025-10-27 15:46:10 +00:00
Fixed #15727 -- Added Content Security Policy (CSP) support.
This initial work adds a pair of settings to configure specific CSP directives for enforcing or reporting policy violations, a new `django.middleware.csp.ContentSecurityPolicyMiddleware` to apply the appropriate headers to responses, and a context processor to support CSP nonces in templates for safely inlining assets. Relevant documentation has been added for the 6.0 release notes, security overview, a new how-to page, and a dedicated reference section. Thanks to the multiple reviewers for their precise and valuable feedback. Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
This commit is contained in:
100
docs/howto/csp.txt
Normal file
100
docs/howto/csp.txt
Normal file
@@ -0,0 +1,100 @@
|
||||
===========================================
|
||||
How to use Django's Content Security Policy
|
||||
===========================================
|
||||
|
||||
.. _csp-config:
|
||||
|
||||
Basic config
|
||||
============
|
||||
|
||||
To enable Content Security Policy (CSP) in your Django project:
|
||||
|
||||
1. Add the CSP middleware to your :setting:`MIDDLEWARE` setting::
|
||||
|
||||
MIDDLEWARE = [
|
||||
# ...
|
||||
"django.middleware.csp.ContentSecurityPolicyMiddleware",
|
||||
# ...
|
||||
]
|
||||
|
||||
2. Configure the CSP policies in your ``settings.py`` using either
|
||||
:setting:`SECURE_CSP` or :setting:`SECURE_CSP_REPORT_ONLY` (or both). The
|
||||
:ref:`CSP Settings docs <csp-settings>` provide more details about the
|
||||
differences between these two::
|
||||
|
||||
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-config:
|
||||
|
||||
Nonce config
|
||||
============
|
||||
|
||||
To use nonces in your CSP policy, beside the basic config, you need to:
|
||||
|
||||
1. Include the :attr:`~django.utils.csp.CSP.NONCE` placeholder value in the CSP
|
||||
settings. This only applies to ``script-src`` or ``style-src`` directives::
|
||||
|
||||
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. Add the :func:`~django.template.context_processors.csp` context processor to
|
||||
your :setting:`TEMPLATES` setting. This makes the generated nonce value
|
||||
available in the Django templates as the ``csp_nonce`` context variable::
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
# ...
|
||||
"django.template.context_processors.csp",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
3. In your templates, add the ``nonce`` attribute to the relevant inline
|
||||
``<style>`` or ``<script>`` tags, using the ``csp_nonce`` context variable:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
<style nonce="{{ csp_nonce }}">
|
||||
/* These inline styles will be allowed. */
|
||||
</style>
|
||||
|
||||
<script nonce="{{ csp_nonce }}">
|
||||
// This inline JavaScript will be allowed.
|
||||
</script>
|
||||
|
||||
.. admonition:: Caching and Nonce Reuse
|
||||
|
||||
The :class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`
|
||||
automatically handles generating a unique nonce and inserting the
|
||||
appropriate ``nonce-<value>`` source expression into the
|
||||
``Content-Security-Policy`` (or ``Content-Security-Policy-Report-Only``)
|
||||
header when the nonce is used in a template.
|
||||
|
||||
To ensure correct behavior, make sure both the HTML and the header are
|
||||
generated within the same request and not served from cache. See the
|
||||
reference documentation on :ref:`csp-nonce` for implementation details and
|
||||
important caching considerations.
|
||||
@@ -57,6 +57,7 @@ Other guides
|
||||
:maxdepth: 1
|
||||
|
||||
auth-remote-user
|
||||
csp
|
||||
csrf
|
||||
custom-file-storage
|
||||
custom-management-commands
|
||||
|
||||
@@ -251,6 +251,7 @@ applications and Django provides multiple protection tools and mechanisms:
|
||||
* :doc:`Cross Site Request Forgery protection <ref/csrf>`
|
||||
* :doc:`Cryptographic signing <topics/signing>`
|
||||
* :ref:`Security Middleware <security-middleware>`
|
||||
* :doc:`Content Security Policy <ref/csp>`
|
||||
|
||||
Internationalization and localization
|
||||
=====================================
|
||||
|
||||
@@ -568,6 +568,8 @@ The following checks are run if you use the :option:`check --deploy` option:
|
||||
``'django-insecure-'`` indicating that it was generated automatically by
|
||||
Django. Please generate a long and random value, otherwise many of Django's
|
||||
security-critical features will be vulnerable to attack.
|
||||
* **security.E026**: The CSP setting ``<SETTING_NAME>`` must be a dictionary
|
||||
(got ``<value>`` instead).
|
||||
|
||||
The following checks verify that your security-related settings are correctly
|
||||
configured:
|
||||
|
||||
210
docs/ref/csp.txt
Normal file
210
docs/ref/csp.txt
Normal file
@@ -0,0 +1,210 @@
|
||||
=======================
|
||||
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
|
||||
<security-csp>`.
|
||||
|
||||
For configuration instructions in a Django project, see the :ref:`Using CSP
|
||||
<csp-config>` documentation. For an HTTP guide about CSP, see the `MDN Guide on
|
||||
CSP <https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP>`_.
|
||||
|
||||
.. _csp-overview:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The `Content-Security-Policy specification <https://www.w3.org/TR/CSP3/>`_
|
||||
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 <csp-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
|
||||
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy#reporting_directives>`_
|
||||
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 (``"<CSP_NONCE_SENTINEL>"``) 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`.
|
||||
|
||||
.. _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
|
||||
``<script>`` or ``<style>`` elements to execute without relying on
|
||||
``'unsafe-inline'``.
|
||||
|
||||
Nonces are enabled by including the special placeholder
|
||||
:attr:`~django.utils.csp.CSP.NONCE` in the relevant directive(s) of your
|
||||
:ref:`CSP settings <csp-settings>`, such as ``script-src`` or ``style-src``.
|
||||
When present, the
|
||||
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`
|
||||
will generate a nonce and insert the corresponding ``nonce-<value>`` source
|
||||
expression into the CSP header.
|
||||
|
||||
To use this nonce in templates, the
|
||||
:func:`~django.template.context_processors.csp` context processor needs to be
|
||||
enabled. It adds a ``csp_nonce`` variable to the template context, allowing
|
||||
inline elements to include a matching ``nonce={{ csp_nonce }}`` attribute in
|
||||
inline scripts or styles.
|
||||
|
||||
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 ``{{ csp_nonce }}`` but the policy does not include
|
||||
:attr:`~django.utils.csp.CSP.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 caching
|
||||
----------------------------
|
||||
|
||||
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 }}``.
|
||||
* 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.
|
||||
@@ -10,6 +10,7 @@ API Reference
|
||||
class-based-views/index
|
||||
clickjacking
|
||||
contrib/index
|
||||
csp
|
||||
csrf
|
||||
databases
|
||||
django-admin
|
||||
|
||||
@@ -607,6 +607,26 @@ You can add Cross Site Request Forgery protection to individual views using the
|
||||
|
||||
Simple :doc:`clickjacking protection via the X-Frame-Options header </ref/clickjacking/>`.
|
||||
|
||||
Content Security Policy middleware
|
||||
----------------------------------
|
||||
|
||||
.. currentmodule:: django.middleware.csp
|
||||
|
||||
.. class:: ContentSecurityPolicyMiddleware
|
||||
|
||||
.. versionadded:: 6.0
|
||||
|
||||
Adds support for Content Security Policy (CSP), which helps mitigate risks such
|
||||
as Cross-Site Scripting (XSS) and data injection attacks by controlling the
|
||||
sources of content that can be loaded in the browser. See the
|
||||
:ref:`csp-overview` documentation for details on configuring policies.
|
||||
|
||||
This middleware sets the following headers on the response depending on the
|
||||
available settings:
|
||||
|
||||
* ``Content-Security-Policy``, based on :setting:`SECURE_CSP`.
|
||||
* ``Content-Security-Policy-Report-Only``, based on :setting:`SECURE_CSP_REPORT_ONLY`.
|
||||
|
||||
.. _middleware-ordering:
|
||||
|
||||
Middleware ordering
|
||||
@@ -691,6 +711,12 @@ Here are some hints about the ordering of various Django middleware classes:
|
||||
After any middleware that modifies the ``Vary`` header: that header is used
|
||||
to pick a value for the cache hash-key.
|
||||
|
||||
#. :class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`
|
||||
|
||||
Can be placed near the bottom, but ensure any middleware that accesses
|
||||
:ref:`csp_nonce <csp-nonce>` is positioned after it, so the nonce is
|
||||
properly included in the response header.
|
||||
|
||||
#. :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`
|
||||
|
||||
Should be near the bottom as it's a last-resort type of middleware.
|
||||
|
||||
@@ -2363,6 +2363,94 @@ Unless set to ``None``, the
|
||||
:ref:`cross-origin-opener-policy` header on all responses that do not already
|
||||
have it to the value provided.
|
||||
|
||||
.. setting:: SECURE_CSP
|
||||
|
||||
``SECURE_CSP``
|
||||
--------------
|
||||
|
||||
.. versionadded:: 6.0
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
This setting defines the directives used by the
|
||||
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`, which
|
||||
generates and adds a :ref:`Content-Security-Policy <csp-overview>` (CSP) header
|
||||
to all responses that do not already include one.
|
||||
|
||||
The ``Content-Security-Policy`` header instructs browsers to restrict which
|
||||
resources a page is allowed to load. A properly configured CSP can block
|
||||
content that violates defined rules, helping prevent cross-site scripting (XSS)
|
||||
and other content injection attacks by explicitly declaring trusted sources for
|
||||
content such as scripts, styles, images, fonts, and more.
|
||||
|
||||
The setting must be a mapping (typically a dictionary) of directive names to
|
||||
their values. Each key should be a valid CSP directive such as ``default-src``
|
||||
or ``script-src``. The corresponding value can be a list, tuple, or set of
|
||||
source expressions or URLs to allow for that directive. If a set is used, it
|
||||
will be automatically sorted to ensure consistent output in the generated
|
||||
headers.
|
||||
|
||||
This example illustrates the expected structure, using the constants defined in
|
||||
:ref:`csp-constants`::
|
||||
|
||||
from django.utils.csp import CSP
|
||||
|
||||
SECURE_CSP = {
|
||||
"default-src": [CSP.SELF],
|
||||
"img-src": ["data:", CSP.SELF, "https://images.example.com"],
|
||||
"frame-src": [CSP.NONE],
|
||||
}
|
||||
|
||||
.. admonition:: Directives validation
|
||||
|
||||
Django's CSP middleware helps construct and send the appropriate header
|
||||
based on your settings, but it does **not validate** that the directives and
|
||||
values conform to the CSP specification. It is your responsibility to ensure
|
||||
that the configuration is syntactically and semantically correct. Use
|
||||
browser developer tools or external CSP validators during development.
|
||||
|
||||
For a list of available directives and their values, refer to the `MDN
|
||||
documentation on CSP directives
|
||||
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives>`_.
|
||||
|
||||
|
||||
.. setting:: SECURE_CSP_REPORT_ONLY
|
||||
|
||||
``SECURE_CSP_REPORT_ONLY``
|
||||
--------------------------
|
||||
|
||||
.. versionadded:: 6.0
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
This setting is just like :setting:`SECURE_CSP`, but instead of enforcing the
|
||||
policy, it instructs the
|
||||
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware` to apply a
|
||||
``Content-Security-Policy-Report-Only`` header to responses, which allows
|
||||
browsers to monitor and report policy violations without blocking content. This
|
||||
is useful for testing and refining a policy before enforcement.
|
||||
|
||||
Most browsers log CSP violations to the developer console and can optionally
|
||||
send them to a reporting endpoint. To collect these reports, the ``report-uri``
|
||||
directive must be defined (see :ref:`csp-reports` for more details).
|
||||
|
||||
As noted in the `MDN documentation on Content-Security-Policy-Report-Only
|
||||
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only>`_,
|
||||
the ``report-uri`` directive must be specified for reports to be sent;
|
||||
otherwise, the header has no reporting effect (other than logging to the
|
||||
browser's developer tools console).
|
||||
|
||||
Following the example from the :setting:`SECURE_CSP` setting::
|
||||
|
||||
from django.utils.csp import CSP
|
||||
|
||||
SECURE_CSP_REPORT_ONLY = {
|
||||
"default-src": [CSP.SELF],
|
||||
"img-src": ["data:", CSP.SELF, "https://images.example.com"],
|
||||
"frame-src": [CSP.NONE],
|
||||
"report-uri": "/my-site/csp/reports/",
|
||||
}
|
||||
|
||||
.. setting:: SECURE_HSTS_INCLUDE_SUBDOMAINS
|
||||
|
||||
``SECURE_HSTS_INCLUDE_SUBDOMAINS``
|
||||
@@ -3749,6 +3837,8 @@ HTTP
|
||||
|
||||
* :setting:`SECURE_CONTENT_TYPE_NOSNIFF`
|
||||
* :setting:`SECURE_CROSS_ORIGIN_OPENER_POLICY`
|
||||
* :setting:`SECURE_CSP`
|
||||
* :setting:`SECURE_CSP_REPORT_ONLY`
|
||||
* :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS`
|
||||
* :setting:`SECURE_HSTS_PRELOAD`
|
||||
* :setting:`SECURE_HSTS_SECONDS`
|
||||
|
||||
@@ -802,6 +802,18 @@ This processor adds a token that is needed by the :ttag:`csrf_token` template
|
||||
tag for protection against :doc:`Cross Site Request Forgeries
|
||||
</ref/csrf>`.
|
||||
|
||||
``django.template.context_processors.csp``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. function:: csp(request)
|
||||
|
||||
.. versionadded:: 6.0
|
||||
|
||||
If this processor is enabled, every ``RequestContext`` will contain a variable
|
||||
``csp_nonce``, providing a securely generated, request-specific nonce suitable
|
||||
for use under a Content Security Policy. See :ref:`CSP nonce usage <csp-nonce>`
|
||||
for details.
|
||||
|
||||
``django.template.context_processors.request``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -37,6 +37,43 @@ compatible with Django 6.0.
|
||||
What's new in Django 6.0
|
||||
========================
|
||||
|
||||
Content Security Policy support
|
||||
-------------------------------
|
||||
|
||||
Built-in support for the :ref:`Content Security Policy (CSP) <security-csp>`
|
||||
standard is now available, making it easier to protect web applications against
|
||||
content injection attacks such as cross-site scripting (XSS). CSP allows
|
||||
declaring trusted sources of content by giving browsers strict rules about
|
||||
which scripts, styles, images, or other resources can be loaded.
|
||||
|
||||
CSP policies can now be enforced or monitored directly using built-in tools:
|
||||
headers are added via the
|
||||
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`, nonces are
|
||||
supported through the :func:`~django.template.context_processors.csp` context
|
||||
processor, and policies are configured using the :setting:`SECURE_CSP` and
|
||||
:setting:`SECURE_CSP_REPORT_ONLY` settings.
|
||||
|
||||
These settings accept Python dictionaries and support Django-provided constants
|
||||
for clarity and safety. For example::
|
||||
|
||||
from django.utils.csp import CSP
|
||||
|
||||
SECURE_CSP = {
|
||||
"default-src": [CSP.SELF],
|
||||
"script-src": [CSP.SELF, CSP.NONCE],
|
||||
"img-src": [CSP.SELF, "https:"],
|
||||
}
|
||||
|
||||
The resulting ``Content-Security-Policy`` header would be set to:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
default-src 'self'; script-src 'self' 'nonce-SECRET'; img-src 'self' https:
|
||||
|
||||
To get started, follow the :doc:`CSP how-to guide </howto/csp>`. For in-depth
|
||||
guidance, see the :ref:`CSP security overview <security-csp>` and the
|
||||
:doc:`reference docs </ref/csp>`.
|
||||
|
||||
Minor features
|
||||
--------------
|
||||
|
||||
|
||||
@@ -310,6 +310,7 @@ needsinfo
|
||||
německy
|
||||
nginx
|
||||
noding
|
||||
nonces
|
||||
nonnegative
|
||||
nullable
|
||||
OAuth
|
||||
|
||||
@@ -286,6 +286,61 @@ User-uploaded content
|
||||
|
||||
.. _same-origin policy: https://en.wikipedia.org/wiki/Same-origin_policy
|
||||
|
||||
.. _security-csp:
|
||||
|
||||
Content Security Policy
|
||||
=======================
|
||||
|
||||
.. versionadded:: 6.0
|
||||
|
||||
Content Security Policy (CSP) is a browser security mechanism that helps
|
||||
protect web applications against attacks such as cross-site scripting (XSS) and
|
||||
other content injection attacks.
|
||||
|
||||
CSP allows web applications to define which sources of content are trusted,
|
||||
instructing the browser to load, execute, or render resources only from those
|
||||
sources. This effectively creates an allowlist of content origins, reducing the
|
||||
risk of malicious code execution.
|
||||
|
||||
Key benefits of enabling CSP include:
|
||||
|
||||
1. Mitigating XSS attacks by blocking inline scripts and restricting external
|
||||
script loading.
|
||||
2. Controlling which external resources (e.g., images, fonts, stylesheets) can
|
||||
be loaded.
|
||||
3. Preventing unwanted framing of your site to protect against clickjacking.
|
||||
4. Reporting violations to a specified endpoint, enabling monitoring and
|
||||
debugging.
|
||||
|
||||
For configuration instructions, see the :ref:`Using CSP <csp-config>`
|
||||
documentation, and refer to the :ref:`CSP overview <csp-overview>` for details
|
||||
on directives and settings.
|
||||
|
||||
Limitations and considerations
|
||||
------------------------------
|
||||
|
||||
While CSP is a powerful security mechanism, it's important to understand its
|
||||
limitations and implications, particularly when used in Django:
|
||||
|
||||
* Policy exclusion risks: Avoid excluding specific paths or responses from
|
||||
CSP protection. Due to the browser’s same-origin policy, a vulnerability on
|
||||
an unprotected page (e.g., one allowing arbitrary script injection) may be
|
||||
leveraged to attack protected pages. Excluding *any* route can significantly
|
||||
weaken the site's overall CSP protection.
|
||||
|
||||
* Performance overhead: Although typically negligible, CSP adds some processing
|
||||
overhead. Nonce generation involves secure randomness for each applicable
|
||||
request. For high-traffic applications or resource-constrained environments,
|
||||
measure the performance impact accordingly.
|
||||
|
||||
* Browser support: While CSP Levels 1 and 2 are widely supported, newer
|
||||
directives (CSP Level 3+) or complex policy behaviors may vary across
|
||||
browsers. Test your policy across the environments you intend to support.
|
||||
|
||||
Despite these limitations, CSP remains an important and recommended security
|
||||
layer for web applications. Understanding its constraints will help you design
|
||||
a more effective and reliable deployment.
|
||||
|
||||
.. _additional-security-topics:
|
||||
|
||||
Additional security topics
|
||||
|
||||
Reference in New Issue
Block a user