Use nonce-based Content Security Policy - #8598
Conversation
It does look like Wagtail has a route to get there, albeit it's been a long one: wagtail/wagtail#1288 |
willbarton
left a comment
There was a problem hiding this comment.
I have a few thoughts. Overall I think this is good, and I don't have much in the way of code review comments, just some additional questions:
- I am curious how this plays with Akamai. Can we find a time slot to deploy it to beta?
- Can we document, with a link to the django-csp docs (and maybe the MDN, or somewhere, CSP docs), when and where one needs to use
request.csp_nonce?
It's unfortunate that we need to override the Wagtail userbar template, but this is clearly something others are doing to solve this exact problem, and Wagtail doesn't offer a good alternative solution.
nonce docs added in bfc4bef |
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-dynamicmode, 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-inlineandhttps:bits are only for backwards compatibility with browsers that support CSP but notstrict-dynamic. Modern browsers ignore these entries whenstrict-dynamicis set. Removingunsafe-evalandunsafe-inlinefrom 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.