Metadata-Version: 2.1
Name: django-csp-advanced
Version: 0.1.0
Summary: Provides a powerful interface to CSP headers for Django applications.
Home-page: https://github.com/quantum5/django-csp-advanced
Author: Quantum
Author-email: quantum@dmoj.ca
License: GNU AGPLv3
Keywords: django csp security
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Description-Content-Type: text/markdown

# django-csp-advanced [![Build Status](https://img.shields.io/travis/quantum5/django-csp-advanced.svg)](https://travis-ci.org/quantum5/django-csp-advanced) [![Coverage](https://img.shields.io/codecov/c/gh/quantum5/django-csp-advanced.svg)](https://codecov.io/gh/quantum5/django-csp-advanced)

A powerful `Content-Security-Policy` (CSP) middleware for Django. This CSP middleware supports
using a dictionary syntax for CSP, and using callables taking arguments `(request, response)`
to fill in parts of the dictionary.

For example, the following `settings.py` configuration:

```python
ADVANCED_CSP = {
    'block-all-mixed-content': True,
    'frame-src': ['none'],
    'plugin-types': ['application/pdf'],
    'report-uri': '/dev/null',
    'sandbox': ['allow-scripts'],
    'script-src': ['self', 'https://dmoj.ca'],
    'style-src': lambda request, response: ['self'],
    'upgrade-insecure-requests': False,
}
```

generates this CSP (order may differ based on dictionary hashing):

```
style-src 'self'; script-src 'self' https://dmoj.ca; frame-src 'none'; plugin-types application/pdf; block-all-mixed-content; sandbox allow-scripts; report-uri /dev/null
```

Another feature is the ability to augment or replace the CSP from views:

```python
def view(request):
    response = HttpResponse()
    response.csp = {'script-src': ['https://ajax.googleapis.com']}
    return response
```

This will add `https://ajax.googleapis.com` to the list of origins listed for `script-src` to result in something like:

```
...; script-src 'self' https://dmoj.ca https://ajax.googleapis.com; ...
```

You can use `'override': True` to replace the CSP instead:

```python
def view(request):
    response = HttpResponse()
    response.csp = {'script-src': ['self'], 'override': True}
    return response
```

This will replace the CSP with `script-src 'self'`.

You can also set `csp_report` on the response to add entry to the report-only CSP.
Note that neither `csp` or `csp_report` has any effect if their global version is disabled.
However, `csp` will be used to populate `Content-Security-Policy-Report-Only` if there is
no enforced CSP policy configured, but there is a report-only policy.

## Installation

First, install the module with:

```
$ pip install django-csp-advanced
```

Or if you want the latest bleeding edge version:

```
$ pip install -e git://github.com/quantum5/django-csp-advanced.git
```

Then, add `'csp_advanced'` to `INSTALLED_APPS` and `'csp_advanced.middleware.AdvancedCSPMiddleware'`
to `'MIDDLEWARE'` or `'MIDDLEWARE_CLASSES'` depending [on your setup](https://docs.djangoproject.com/en/dev/topics/http/middleware/).

Finally, use either a dictionary or a callable taking `request, response` as either
`ADVANCED_CSP` or `ADVANCED_CSP_REPORT_ONLY`.

Examples:

```python
ADVANCED_CSP = lambda request, response: {'script-src': ['self']}

ADVANCED_CSP_REPORT_ONLY = {'script-src': ['self']}

ADVANCED_CSP = {'style-src': lambda request, response: ['self']}
```

You get the idea.


