Configuring django-csp
Content-Security-Policy is a complicated header. There are many values you may need to tweak here.
It’s worth reading the latest CSP spec and making sure you understand it before configuring django-csp.
Note
Many settings require a tuple
or list
. You may get very strange
policies and even errors when mistakenly configuring them as a string
.
Migrating from django-csp <= 3.8
Version 4.0 of django-csp introduces a new configuration format that breaks compatibility with previous versions. If you are migrating from django-csp 3.8 or lower, you will need to update your settings to the new format. See the migration guide for more information.
Configuration
All configuration of django-csp is done in your Django settings file with the
CONTENT_SECURITY_POLICY
setting or the CONTENT_SECURITY_POLICY_REPORT_ONLY
setting. Each of these
settings expects a dictionary representing a policy.
The CONTENT_SECURITY_POLICY
setting is your enforceable policy.
The CONTENT_SECURITY_POLICY_REPORT_ONLY
setting is your report-only policy. This policy is
used to test the policy without breaking the site. It is useful when setting this policy to be
slightly more strict than the default policy to see what would be blocked if the policy was enforced.
The following is an example of a policy configuration with a default policy and a report-only policy. The default policy is considered a “relaxed” policy that allows for the most flexibility while still providing a good level of security. The report-only policy is considered a step towards a more slightly strict policy and is used to test the policy without breaking the site.
from csp.constants import NONE, SELF
CONTENT_SECURITY_POLICY = {
"EXCLUDE_URL_PREFIXES": ["/excluded-path/"],
"DIRECTIVES": {
"default-src": [SELF, "cdn.example.net"],
"frame-ancestors": [SELF],
"form-action": [SELF],
"report-uri": "/csp-report/",
},
}
CONTENT_SECURITY_POLICY_REPORT_ONLY = {
"EXCLUDE_URL_PREFIXES": ["/excluded-path/"],
"DIRECTIVES": {
"default-src": [NONE],
"connect-src": [SELF],
"img-src": [SELF],
"form-action": [SELF],
"frame-ancestors": [SELF],
"script-src": [SELF],
"style-src": [SELF],
"upgrade-insecure-requests": True,
"report-uri": "/csp-report/",
},
}
Note
In the above example, the constant NONE
is converted to the CSP keyword "'none'"
and
is distinct from Python’s None
value. The CSP keyword 'none'
is a special value that
signifies that you do not want any sources for this directive. The None
value is a
Python keyword that represents the absence of a value and when used as the value of a directive,
it will remove the directive from the policy.
This is useful when using the @csp_replace
decorator to effectively clear a directive from
the base configuration as defined in the settings. For example, if the Django settings the
frame-ancestors
directive is set to a list of sources and you want to remove the
frame-ancestors
directive from the policy for this view:
from csp.decorators import csp_replace
@csp_replace({"frame-ancestors": None})
def my_view(request): ...
Policy Settings
At the top level of the policy dictionary, these are the keys that can be used to configure the policy.
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.REPORT_PERCENTAGE
Percentage of requests that should see the
report-uri
directive. Use this to throttle the number of CSP violation reports made to yourreport-uri
. A float between 0.0 and 100.0 (0.0 = no reports at all, 100.0 = always report). Ignored ifreport-uri
isn’t set.DIRECTIVES
A dictionary of policy directives. Each key in the dictionary is a directive and the value is a list of sources for that directive. The following is a list of all the directives that can be configured.
Note
The CSP keyword values of
'self'
,'unsafe-inline'
,'strict-dynamic'
, etc. must be quoted! e.g.:"default-src": ["'self'"]
. Without quotes they will not work as intended.New in version 4.0 are CSP keyword constants. Use these to minimize quoting mistakes and typos.
The following CSP keywords are available:
NONE
="'none'"
REPORT_SAMPLE
="'report-sample'"
SELF
="'self'"
STRICT_DYNAMIC
="'strict-dynamic'"
UNSAFE_ALLOW_REDIRECTS
="'unsafe-allow-redirects'"
UNSAFE_EVAL
="'unsafe-eval'"
UNSAFE_HASHES
="'unsafe-hashes'"
UNSAFE_INLINE
="'unsafe-inline'"
WASM_UNSAFE_EVAL
="'wasm-unsafe-eval'"
Example usage:
from csp.constants import SELF, STRICT_DYNAMIC CONTENT_SECURITY_POLICY = { "DIRECTIVES": { "default-src": [SELF, "cdn.example.net"], "script-src": [SELF, STRICT_DYNAMIC], "style-src": [SELF], } }
Note
Deprecated features of CSP in general have been moved to the bottom of this list.
Warning
The
'unsafe-inline'
and'unsafe-eval'
sources are considered harmful and should be avoided. They are included here for completeness, but should not be used in production.default-src
Set the
default-src
directive. Atuple
orlist
of values, e.g.:("'self'", 'cdn.example.net')
. [“‘self’”]script-src
Set the
script-src
directive. Atuple
orlist
. Nonescript-src-attr
Set the
script-src-attr
directive. Atuple
orlist
. Nonescript-src-elem
Set the
script-src-elem
directive. Atuple
orlist
. Noneimg-src
Set the
img-src
directive. Atuple
orlist
. Noneobject-src
Set the
object-src
directive. Atuple
orlist
. Nonemedia-src
Set the
media-src
directive. Atuple
orlist
. Noneframe-src
Set the
frame-src
directive. Atuple
orlist
. Nonefont-src
Set the
font-src
directive. Atuple
orlist
. Noneconnect-src
Set the
connect-src
directive. Atuple
orlist
. Nonestyle-src
Set the
style-src
directive. Atuple
orlist
. Nonestyle-src-attr
Set the
style-src-attr
directive. Atuple
orlist
. Nonestyle-src-elem
Set the
style-src-elem
directive. Atuple
orlist
. Nonebase-uri
Set the
base-uri
directive. Atuple
orlist
. NoneNote: This doesn’t use
default-src
as a fall-back.child-src
Set the
child-src
directive. Atuple
orlist
. Noneframe-ancestors
Set the
frame-ancestors
directive. Atuple
orlist
. NoneNote: This doesn’t use
default-src
as a fall-back.navigate-to
Set the
navigate-to
directive. Atuple
orlist
. NoneNote: This doesn’t use
default-src
as a fall-back.form-action
Set the
FORM_ACTION
directive. Atuple
orlist
. NoneNote: This doesn’t use
default-src
as a fall-back.sandbox
Set the
sandbox
directive. Atuple
orlist
. NoneNote: This doesn’t use
default-src
as a fall-back.report-uri
Set the
report-uri
directive. Atuple
orlist
of URIs. Each URI can be a full or relative URI. NoneNote: This doesn’t use
default-src
as a fall-back.report-to
Set the
report-to
directive. Astring
describing a reporting group. NoneSee Section 1.2: https://w3c.github.io/reporting/#group
Also see this MDN note on
report-uri
andreport-to
.manifest-src
Set the
manifest-src
directive. Atuple
orlist
. Noneworker-src
Set the
worker-src
directive. Atuple
orlist
. Nonerequire-sri-for
Set the
require-sri-for
directive. Atuple
orlist
. NoneValid values: a
list
containing'script'
,'style'
, or both.upgrade-insecure-requests
Include
upgrade-insecure-requests
directive. Aboolean
. Falserequire-trusted-types-for
Include
require-trusted-types-for
directive. Atuple
orlist
. NoneValid values:
["'script'"]
trusted-types
Include
trusted-types
directive. Atuple
orlist
. NoneValid values: a
list
of allowed policy names that may includedefault
and/or'allow-duplicates'
Deprecated CSP settings
The following DIRECTIVES
settings are still configurable, but are considered deprecated
in terms of the latest implementation of the relevant spec.
block-all-mixed-content
Include
block-all-mixed-content
directive. Aboolean
. FalseRelated note on MDN.
Spec: block-all-mixed-content
plugin-types
Set the
plugin-types
directive. Atuple
orlist
. NoneNote: This doesn’t use
default-src
as a fall-back.Related note on MDN.
prefetch-src
Set the
prefetch-src
directive. Atuple
orlist
. NoneRelated note on MDN.
Changing the Policy
The policy can be changed on a per-view (or even per-request) basis. See the decorator documentation for more details.