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_PREFIXESA
tupleof 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_PERCENTAGEPercentage of requests that should see the
report-uridirective. 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-uriisn’t set.Note
To allow rate limiting,
csp.contrib.rate_limiting.RateLimitedCSPMiddlewaremust be used instead ofcsp.middleware.CSPMiddleware. See violation reporting for more details.DIRECTIVESA 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-srcSet the
default-srcdirective. Atupleorlistof values, e.g.:("'self'", 'cdn.example.net'). [“‘self’”]script-srcSet the
script-srcdirective. Atupleorlist. Nonescript-src-attrSet the
script-src-attrdirective. Atupleorlist. Nonescript-src-elemSet the
script-src-elemdirective. Atupleorlist. Noneimg-srcSet the
img-srcdirective. Atupleorlist. Noneobject-srcSet the
object-srcdirective. Atupleorlist. Nonemedia-srcSet the
media-srcdirective. Atupleorlist. Noneframe-srcSet the
frame-srcdirective. Atupleorlist. Nonefont-srcSet the
font-srcdirective. Atupleorlist. Noneconnect-srcSet the
connect-srcdirective. Atupleorlist. Nonestyle-srcSet the
style-srcdirective. Atupleorlist. Nonestyle-src-attrSet the
style-src-attrdirective. Atupleorlist. Nonestyle-src-elemSet the
style-src-elemdirective. Atupleorlist. Nonebase-uriSet the
base-uridirective. Atupleorlist. NoneNote: This doesn’t use
default-srcas a fall-back.child-srcSet the
child-srcdirective. Atupleorlist. Noneframe-ancestorsSet the
frame-ancestorsdirective. Atupleorlist. NoneNote: This doesn’t use
default-srcas a fall-back.navigate-toSet the
navigate-todirective. Atupleorlist. NoneNote: This doesn’t use
default-srcas a fall-back.form-actionSet the
FORM_ACTIONdirective. Atupleorlist. NoneNote: This doesn’t use
default-srcas a fall-back.sandboxSet the
sandboxdirective. Atupleorlist. NoneNote: This doesn’t use
default-srcas a fall-back.report-uriSet the
report-uridirective. Atupleorlistof URIs. Each URI can be a full or relative URI. NoneNote: This doesn’t use
default-srcas a fall-back.report-toSet the
report-todirective. Astringdescribing a reporting group. NoneSee Section 1.2: https://w3c.github.io/reporting/#group
Also see this MDN note on
report-uriandreport-to.manifest-srcSet the
manifest-srcdirective. Atupleorlist. Noneworker-srcSet the
worker-srcdirective. Atupleorlist. Nonerequire-sri-forSet the
require-sri-fordirective. Atupleorlist. NoneValid values: a
listcontaining'script','style', or both.upgrade-insecure-requestsInclude
upgrade-insecure-requestsdirective. Aboolean. Falserequire-trusted-types-forInclude
require-trusted-types-fordirective. Atupleorlist. NoneValid values:
["'script'"]trusted-typesInclude
trusted-typesdirective. Atupleorlist. NoneValid values: a
listof allowed policy names that may includedefaultand/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-contentInclude
block-all-mixed-contentdirective. Aboolean. FalseRelated note on MDN.
Spec: block-all-mixed-content
plugin-typesSet the
plugin-typesdirective. Atupleorlist. NoneNote: This doesn’t use
default-srcas a fall-back.Related note on MDN.
prefetch-srcSet the
prefetch-srcdirective. Atupleorlist. 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.