Use nonce-based Content Security Policy #8598
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This updates our CSP to use nonces, provided by Django-csp. This shrinks the size of the CSP header by ~7x while increasing its security. The main mechanism of CSP enforcement is
strict-dynamic
mode, which requires a nonce (or hash) for any script element included in the html, but allows the creation of further script elements from trusted scripts (so we don't have to specifically allow a bunch of random third-party domains if we're already trusting their initiators).Note: the
unsafe-inline
andhttps:
bits are only for backwards compatibility with browsers that support CSP but notstrict-dynamic
. Modern browsers ignore these entries whenstrict-dynamic
is set. Removingunsafe-eval
andunsafe-inline
from our CSP will increase its efficacy incredibly :)Because we're much more secure-by-default, I've also removed a bunch of the other IMG/STYLE/etc CSP settings which are now less important (because XSS to then include bad domains/styles is harder).
Another important note: due to limitations in how Wagtail includes scripts in the admin, I've made admin pages exclude the CSP. This isn't actually a problem because these pages are excluded from the public website. The only other solution of this was to override several base wagtail templates, which seemed like a big maintenance headache (for no real benefit). One exception to this was this the wagtail userbar, which I needed to override so to get working.