Search code examples
facebooksecuritytwitterhttp-headerscontent-security-policy

How to understand the Content-Security-Policy (CSP) rules by the popular websites?


Recently I was doing some research on CSP, and I found some weird declarations of CSP from dominant websites.

For Facebook, after logging in, the CSP is like:

default-src * data: blob: 'self';
script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.google.com 127.0.0.1:* 'unsafe-inline' 'unsafe-eval' blob: data: 'self';
style-src data: blob: 'unsafe-inline' *;
connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net wss://*.facebook.com:* wss://*.whatsapp.com:* attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self';
block-all-mixed-content;
upgrade-insecure-requests;

What confused me is that default-src uses an asteroid(*) and then follows with other stricter rules ('self'):

default-src * data: blob: 'self';

In my recent studies, the asteroid syntax is usually not suggested which will make your website insecure. And I cannot figure out what is the final effect of this rule, if self always overrides *, then why leave a redundant *.

As for Twitter, their CSP is like:

connect-src 'self' blob: https://*.giphy.com https://*.pscp.tv https://*.video.pscp.tv https://*.twimg.com https://api.twitter.com https://api-stream.twitter.com https://ads-api.twitter.com https://aa.twitter.com https://caps.twitter.com https://media.riffsy.com https://pay.twitter.com https://sentry.io https://ton.twitter.com https://twitter.com https://upload.twitter.com https://www.google-analytics.com https://app.link https://api2.branch.io https://bnc.lt wss://*.pscp.tv https://vmap.snappytv.com https://vmapstage.snappytv.com https://vmaprel.snappytv.com https://vmap.grabyo.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net ; 
default-src 'self'; 
form-action 'self' https://twitter.com https://*.twitter.com; 
font-src 'self' https://*.twimg.com; 
frame-src 'self' https://twitter.com https://mobile.twitter.com https://pay.twitter.com https://cards-frame.twitter.com   https://accounts.google.com/; 
img-src 'self' blob: data: https://*.cdn.twitter.com https://ton.twitter.com https://*.twimg.com https://analytics.twitter.com https://cm.g.doubleclick.net https://www.google-analytics.com https://www.periscope.tv https://www.pscp.tv https://media.riffsy.com https://*.giphy.com https://*.pscp.tv https://*.periscope.tv https://prod-periscope-profile.s3-us-west-2.amazonaws.com https://platform-lookaside.fbsbx.com https://scontent.xx.fbcdn.net https://scontent-sea1-1.xx.fbcdn.net https://*.googleusercontent.com https://imgix.revue.co; 
manifest-src 'self'; 
media-src 'self' blob: https://twitter.com https://*.twimg.com https://*.vine.co https://*.pscp.tv https://*.video.pscp.tv https://*.giphy.com https://media.riffsy.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net; 
object-src 'none'; 
script-src 'self' 'unsafe-inline' https://*.twimg.com    https://www.google-analytics.com https://twitter.com https://app.link https://accounts.google.com/gsi/client https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js  'nonce-ODdiNzNlNGYtNjFmNS00ZmYxLWE0ZjctODViNTU5YmI4Zjk5'; 
style-src 'self' 'unsafe-inline' https://accounts.google.com/gsi/style https://*.twimg.com; 
worker-src 'self' blob:; 
report-uri https://twitter.com/i/csp_report?a=O5RXE%3D%3D%3D&ro=false

what confused me is the script-src:

script-src 'self' 'unsafe-inline' https://*.twimg.com https://www.google-analytics.com https://twitter.com https://app.link https://accounts.google.com/gsi/client https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js  'nonce-ODdiNzNlNGYtNjFmNS00ZmYxLWE0ZjctODViNTU5YmI4Zjk5'; 

I thought nonce is designed to prevent the usage of unsafe-inline, but in the above directive, both exist. Again, my question is if the latter overrides the former, why leave a redundant unsafe-inline.


Solution

  • default-src * data: blob: 'self';
    

    In my recent studies, the asteroid syntax is usually not suggested which will make your website insecure.

    That's generally yes, but most potentially dangerous for XSS the script-src and connect-src directives have their own whitelist of sources without *.
    For the remaining fallback-directives, the asterisk * is not a dangerous source (maybe except object-src), on the contrary, it is necessary because the list of third-party hosts for hosting images or media content can be endless.

    And I cannot figure out what is the final effect of this rule, if 'self' always overrides *, then why leave a redundant *.

    Actually it's * overrides 'self'. And yes, the 'self' is redundant when using *. In large companies, IT specialists do not like to touch what works. I think that "self" just remained as an atavism after some researches, because some older Safari had a bug with 'self'.

    I thought nonce is designed to prevent the usage of unsafe-inline, but in the above directive, both exist.

    This was made for browsers backward compatibility.
    In the presence of a CSP nonce the 'unsafe-inline' will be ignored by modern browsers. Older browsers, which don't support nonces, will see 'unsafe-inline' and allow inline scripts to execute.