django-csp

django-csp adds Content-Security-Policy headers to Django applications.

Version:3.4
Code:https://github.com/mozilla/django-csp
License:BSD; see LICENSE file
Issues:https://github.com/mozilla/django-csp/issues

Contents:

Installing django-csp

First, install django-csp via pip or from source:

# pip
$ pip install django-csp
# source
$ git clone https://github.com/mozilla/django-csp.git
$ cd django-csp
$ python setup.py install

Now edit your project’s settings module, to add the django-csp middleware to MIDDLEWARE_CLASSES, like so:

MIDDLEWARE_CLASSES = (
    # ...
    'csp.middleware.CSPMiddleware',
    # ...
)

That should do it! Go on to configuring CSP.

Configuring django-csp

Content-Security-Policy is a complicated header. There are many values you may need to tweak here.

Note

Note when a setting requires a tuple or list. Since Python strings are iterable, you may get very strange policies and errors.

It’s worth reading the latest CSP spec and making sure you understand it before configuring django-csp.

Policy Settings

These settings affect the policy in the header. The defaults are in italics.

Note

The “special” source values of 'self', 'unsafe-inline', 'unsafe-eval', and 'none' must be quoted! e.g.: CSP_DEFAULT_SRC = ("'self'",). Without quotes they will not work as intended.

CSP_DEFAULT_SRC
Set the default-src directive. A tuple or list of values, e.g. ("'self'", 'cdn.example.net'). ‘self’
CSP_SCRIPT_SRC
Set the script-src directive. A tuple or list. None
CSP_IMG_SRC
Set the img-src directive. A tuple or list. None
CSP_OBJECT_SRC
Set the object-src directive. A tuple or list. None
CSP_MEDIA_SRC
Set the media-src directive. A tuple or list. None
CSP_FRAME_SRC
Set the frame-src directive. A tuple or list. None
CSP_FONT_SRC
Set the font-src directive. A tuple or list. None
CSP_CONNECT_SRC
Set the connect-src directive. A tuple or list. None
CSP_STYLE_SRC
Set the style-src directive. A tuple or list. None
CSP_BASE_URI
Set the base-uri directive. A tuple or list. None Note: This doesn’t use default-src as a fall-back.
CSP_CHILD_SRC
Set the child-src directive. A tuple or list. None Note: Deprecated in CSP v3. Use frame-src and worker-src instead.
CSP_FRAME_ANCESTORS
Set the FRAME_ANCESTORS directive. A tuple or list. None Note: This doesn’t use default-src as a fall-back.
CSP_FORM_ACTION
Set the FORM_ACTION directive. A tuple or list. None Note: This doesn’t use default-src as a fall-back.
CSP_SANDBOX
Set the sandbox directive. A tuple or list. None Note: This doesn’t use default-src as a fall-back.
CSP_REPORT_URI
Set the report-uri directive. A string with a full or relative URI. Note: This doesn’t use default-src as a fall-back.
CSP_MANIFEST_SRC
Set the manifest-src directive. A tuple or list. None
CSP_WORKER_SRC
Set the worker-src directive. A tuple or list. None
CSP_PLUGIN_TYPES
Set the plugin-types directive. A tuple or list. None Note: This doesn’t use default-src as a fall-back.
CSP_REQUIRE_SRI_FOR
Set the require-sri-for directive. A tuple or list. None Valid values: script, style, or both. See: require-sri-for-known-tokens Note: This doesn’t use default-src as a fall-back.
CSP_UPGRADE_INSECURE_REQUESTS
Include upgrade-insecure-requests directive. A boolean. False See: upgrade-insecure-requests
CSP_BLOCK_ALL_MIXED_CONTENT
Include block-all-mixed-content directive. A boolean. False See: block-all-mixed-content

Changing the Policy

The policy can be changed on a per-view (or even per-request) basis. See the decorator documentation for more details.

Other Settings

These settings control the behavior of django-csp. Defaults are in italics.

CSP_REPORT_ONLY
Send “report-only” headers instead of real headers. See the spec and the chapter on reports for more info. A boolean. False
CSP_EXCLUDE_URL_PREFIXES
A tuple of URL prefixes. URLs beginning with any of these will not get the CSP headers. ()

Warning

Excluding any path on your site will eliminate the benefits of CSP everywhere on your site. The typical browser security model for JavaScript considers all paths alike. A Cross-Site Scripting flaw on, e.g., excluded-page/ can therefore be leveraged to access everything on the same origin.

Modifying the Policy with Decorators

Content Security Policies should be restricted and paranoid by default. You may, on some views, need to expand or change the policy. django-csp includes four decorators to help.

@csp_exempt

Using the @csp_exempt decorator disables the CSP header on a given view.

from csp.decorators import csp_exempt

# Will not have a CSP header.
@csp_exempt
def myview(request):
    return render(...)

You can manually set this on a per-response basis by setting the _csp_exempt attribute on the response to True:

# Also will not have a CSP header.
def myview(request):
    response = render(...)
    response._csp_exempt = True
    return response

@csp_update

The @csp_update header allows you to append values to the source lists specified in the settings. If there is no setting, the value passed to the decorator will be used verbatim.

Note

To quote the CSP spec: “There’s no inheritance; … the default list is not used for that resource type” if it is set. E.g., the following will not allow images from ‘self’:

default-src 'self'; img-src imgsrv.com

The arguments to the decorator the same as the settings without the CSP_ prefix, e.g. IMG_SRC. (They are also case-insensitive.) The values are either strings, lists or tuples.

from csp.decorators import csp_update

# Will allow images from imgsrv.com.
@csp_update(IMG_SRC='imgsrv.com')
def myview(request):
    return render(...)

@csp_replace

The @csp_replace decorator allows you to replace a source list specified in settings. If there is no setting, the value passed to the decorator will be used verbatim. (See the note under @csp_update.)

The arguments and values are the same as @csp_update:

from csp.decorators import csp_replace

# settings.CSP_IMG_SRC = ['imgsrv.com']
# Will allow images from imgsrv2.com, but not imgsrv.com.
@csp_replace(IMG_SRC='imgsrv2.com')
def myview(request):
    return render(...)

@csp

If you need to set the entire policy on a view, ignoring all the settings, you can use the @csp decorator. The arguments and values are as above:

from csp.decorators import csp

@csp(DEFAULT_SRC=["'self'"], IMG_SRC=['imgsrv.com'],
     SCRIPT_SRC=['scriptsrv.com', 'googleanalytics.com'])
def myview(request):
    return render(...)

CSP Violation Reports

When something on a page violates the Content-Security-Policy, and the policy defines a report-uri directive, the user agent may POST a report. Reports are JSON blobs containing information about how the policy was violated.

Note: django-csp no longer handles report processing itself, so you will need to stand up your own app to receive them, or else make use of a third-party report processing service.

Contributing

Patches are more than welcome! You can find the issue tracker on GitHub and we’d love pull requests.

Style

Patches should follow PEP8 and should not introduce any new violations as detected by the flake8 tool.

Tests

Patches fixing bugs should include regression tests (ideally tests that fail without the rest of the patch). Patches adding new features should test those features thoroughly.

To run the tests, install the requirements (probably into a virtualenv):

pip install -e .
pip install -e .[tests]

Then just py.test to run the tests:

py.test

Indices and tables