I have a large, legacy codebase that I'd like to introduce the Content-Security-Policy
header on. It is not feasible in the short term to truly lock-down the site (for example, there are inline scripts all over the place that have no automated test coverage), but at least I can start by forbidding access to content sources that I know for sure aren't in use currently and then slowly ratchet it down over time.
Unfortunately, the list of sources that aren't being used is rather short. This was my first attempt at a Content-Security-Policy
value:
default-src * 'unsafe-eval' 'unsafe-inline'
That broke a number of things, such as images sourced using the data: scheme. Looking around, I see a number of things you might want to include, such as connect-src ws:
, that aren't explicitly called out in the docs.
What is the maximally permissive Content-Security-Policy
header value that basically lets the site do everything the browser is allowed to do by default? Asked another way: what header value can I introduce that definitely won't break anything on the site?
I'd feel more comfortable introducing the header into the legacy site if I could start with something that I know won't break anything, then subtract out the permissions that I know are safe to remove.
A strict content security policy is based on nonces or hashes. Using a strict CSP prevents hackers from using HTML injection flaws to force the browser to execute the malicious script. The policy is especially effective against classical stored, reflected, and various DOM XSS attacks.
The HTTP Content-Security-Policy (CSP) default-src directive serves as a fallback for the other CSP fetch directives. For each of the following directives that are absent, the user agent looks for the default-src directive and uses this value for it: child-src.
Click the extension icon to disable Content-Security-Policy header for the tab. Click the extension icon again to re-enable Content-Security-Policy header. Use this only as a last resort. Disabling Content-Security-Policy means disabling features designed to protect you from cross-site scripting.
tl;dr use "report only" mode to introduce a policy to a legacy site.
See w3.org/TR/CSP2/#source-list-guid-matching.
As defined above, special URL schemes that refer to specific pieces of unique content, such as "data:", "blob:" and "filesystem:" are excluded from matching a policy of * and must be explicitly listed.
Therefor, something along the lines of default-src * 'unsafe-eval' 'unsafe-inline' 'unsafe-dynamic' data: filesystem: about: blob: ws: wss:
is probably close to the most lenient policy. There are more protocols that may need to be whitelisted, of course.
HOWEVER
Typically people take the opposite approach. They will deploy the header with Content-Security-Policy-Report-Only: default-src 'none'
which will not affect the loading of your site and will allow you to ratchet down your policy based on the violations or console warnings.
I highly recommend you start with the caspr chrome extension to create an initial policy and then use report-uri.io to view report violations. When your policy seems stable and violations are minimal, then switch your policy to enforce mode.
Try
default-src * data: blob: filesystem: about: ws: wss: 'unsafe-inline' 'unsafe-eval' 'unsafe-dynamic';
script-src * 'unsafe-inline' 'unsafe-eval';
connect-src * 'unsafe-inline';
img-src * data: blob: 'unsafe-inline';
frame-src *;
style-src * data: blob: 'unsafe-inline';
font-src * data: blob: 'unsafe-inline';
Even with this, you might still find violations, if you find them, report it to me!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With