13

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.

Community
  • 1
  • 1
Michael Kropat
  • 14,557
  • 12
  • 70
  • 91

2 Answers2

19

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.

oreoshake
  • 4,712
  • 1
  • 31
  • 38
  • 1
    Cool. I particularly appreciate that you both answered the question as asked and pointed out a probably better way to do it (caspr extension and using reporting mode, which I had overlooked). I'm going to try it out. – Michael Kropat Jul 20 '16 at 14:38
  • This still gives me an `Refused to load the image` error :) – hugo der hungrige Jul 05 '18 at 22:09
  • @hugoderhungrige if you provide the full error message I assure you we can update this. Without that information, it's impossible to guess what happened. – oreoshake Jul 07 '18 at 23:46
  • @oreoshake my bad. The error was related to some proxy configuration, not the CSP. – hugo der hungrige Jul 07 '18 at 23:50
4

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!

Rainb
  • 1,965
  • 11
  • 32