Skip to content

Commit

Permalink
Update migration guide to include decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
robhudson committed May 25, 2024
1 parent ebfe1bd commit d2cd3e2
Showing 1 changed file with 82 additions and 23 deletions.
105 changes: 82 additions & 23 deletions docs/migration-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ Overview

In the latest version of `django-csp`, the format for configuring Content Security Policy (CSP)
settings has been updated are are backwards-incompatible with prior versions. The previous approach
of using individual settings prefixed with ``CSP_`` for each directive is no longer valid. Instead,
all CSP settings are now consolidated into one of two dict-based settings: ``CONTENT_SECURITY_POLICY``
or ``CONTENT_SECURITY_POLICY_REPORT_ONLY``.
of using individual settings prefixed with ``CSP_`` for each directive is no longer supported.
Instead, all CSP settings are now consolidated into one of two dict-based settings:
``CONTENT_SECURITY_POLICY`` or ``CONTENT_SECURITY_POLICY_REPORT_ONLY``.

Migrating from the Old Settings Format
======================================

Step 1: Update `django-csp` Version
-----------------------------------
Update `django-csp`
-------------------

First, update the `django-csp` package to the latest version that supports the new settings format.
You can do this by running:
Expand All @@ -26,8 +26,8 @@ You can do this by running:
pip install -U django-csp
Step 2: Add the `csp` app to `INSTALLED_APPS`
---------------------------------------------
Add the `csp` app to `INSTALLED_APPS`
-------------------------------------

In your Django project's `settings.py` file, add the `csp` app to the ``INSTALLED_APPS`` setting:

Expand All @@ -39,10 +39,11 @@ In your Django project's `settings.py` file, add the `csp` app to the ``INSTALLE
...
]
Step 3: Run the Django check command
------------------------------------
Run the Django check command
----------------------------

Run the Django check command to get a settings config based on your existing CSP settings:
This is optional but can help kick start the new settings configuration for you. Run the Django
check command which will look for old settings and output a configuration in the new format:

.. code-block:: bash
Expand All @@ -51,22 +52,22 @@ Run the Django check command to get a settings config based on your existing CSP
This can help you identify the existing CSP settings in your project and provide a starting point
for migrating to the new format.

Step 4: Identify Existing CSP Settings
--------------------------------------
Identify Existing CSP Settings
------------------------------

Locate all the existing CSP settings in your Django project. These settings typically start with the
Locate all the existing CSP settings in your Django project. These settings start with the
``CSP_`` prefix, such as ``CSP_DEFAULT_SRC``, ``CSP_SCRIPT_SRC``, ``CSP_IMG_SRC``, etc.

Step 5: Create the New Settings Dictionary
------------------------------------------
Create the New Settings Dictionary
----------------------------------

In your Django project's `settings.py` file, create a new dictionary called
``CONTENT_SECURITY_POLICY`` or ``CONTENT_SECURITY_POLICY_REPORT_ONLY``, depending on whether you want to
enforce the policy or only report violations. Use the output from the Django check command as a
starting point to populate this dictionary.
enforce the policy or only report violations, or both. Use the output from the Django check command
as a starting point to populate this dictionary.

Step 6: Migrate Existing Settings
---------------------------------
Migrate Existing Settings
-------------------------

Migrate your existing CSP settings to the new format by populating the ``DIRECTIVES`` dictionary
inside the ``CONTENT_SECURITY_POLICY`` setting. The keys of the ``DIRECTIVES`` dictionary should be the
Expand Down Expand Up @@ -95,15 +96,73 @@ The new settings would be:
},
}
Note that the directive names in the ``DIRECTIVES`` dictionary are in lowercase and use dashes instead
of underscores.
.. note::

Step 7: Remove Old Settings
---------------------------
The keys in the ``DIRECTIVES`` dictionary, the directive names, are in lowercase and use dashes
instead of underscores to match the CSP specification.

.. note::

If you were using the ``CSP_REPORT_PERCENTAGE`` setting, this should be updated to be an integer
percentage and not a decimal value in the new settings format. For example, if you had
``CSP_REPORT_PERCENTAGE = 0.1``, this should be updated to:

.. code-block:: python
CONTENT_SECURITY_POLICY = {
"REPORT_PERCENTAGE": 10,
"DIRECTIVES": {
"report-uri": "/csp-report/",
...
},
}
Remove Old Settings
-------------------

After migrating to the new settings format, remove all the old ``CSP_`` prefixed settings from your
`settings.py` file.

Update the CSP decorators
-------------------------

If you are using the CSP decorators in your views, those will need to be updated as well. The
decorators now accept a dictionary containing the CSP directives as an argument. For example:

.. code-block:: python
from csp.decorators import csp_update
@csp_update({"default-src": ["another-url.com"]})
def my_view(request):
...
Additionally, each decorator now takes an optional ``report_only`` argument to specify whether the
policy should be enforced or only report violations. For example:

.. code-block:: python
from csp.decorators import csp
@csp({"default-src": ["'self'"]}, report_only=True)
def my_view(request):
...
Due to the addition of the ``report_only`` argument and for consistency, the ``csp_exempt``
decorator now requires parentheses when used with and without arguments. For example:

.. code-block:: python
from csp.decorators import csp_exempt
@csp_exempt()
@csp_exempt(report_only=True)
def my_view(request):
...
Look for uses of the following decorators in your code: ``@csp``, ``@csp_update``, ``@csp_replace``,
and ``@csp_exempt``.

Conclusion
==========

Expand Down

0 comments on commit d2cd3e2

Please sign in to comment.