Can Content Security Policy prevent content injection and man-in-the-middle attacks? This is an expanded version of a discussion we had with @synackpse and @bryanbrake after my CSP podcast last month. If the purpose of CSP is to declare a whitelist of content sources authorised to load on current website, can it prevent rogue content from being injected? We’re talking about the following scenarios:
- Content injection into plaintext HTTP connections by the ISP or hotspot operator as Comcast, R66T and others did;
- Local operating system injection into plain-text and TLS connections by malware, spyware or adware, as Superfish did (powered by Komodia SDK using rogue certificate);
- Rogue content injection into websites as result of various attack on the web applications or their hosting infrastructure, as it happened to RedTube
There is no single answer here: in each of these cases CSP can or cannot prevent the injection, depending on how the policy is contructed and how the attack is executed in details. Let's see on how they actually did look like.
"/><meta nm="Archives - Free Porn Videos - The Free Porn Tube Video Site - YOXVIDEOS.COM</code> SuperFish local injection into SSL/TLS connection. This sample comes from PasteBin, not sure how much up to date it is, but if it's what SuperFish still does, then CSP will easily block it due to a non-whitelisted source:
<!DOCTYPE html> </code> CSP is completely bypassed because the rogue content is injected in a way that makes is look like coming from the original website. None of these priv.dog.preload scripts are present of course on the actual website, here's the original source code for comparison:
Best practicesThe following recommendations can be derived from the samples presented above:
- Do use Strict Transport Security, Public Key Pinns and CSP in enforcement mode. They did block most of the rogue script injections in the above real-life non-local scenarios. And, judging from large number of violation reports from SuperFish I see on CspBuilder, they will block the less clever local injections as well.
- Realy avoid unsafe-inline and unsafe-eval in CSP. Allowing inline scripts essentially opens door to even dumbest injections, especially if no TLS is used. If you need to allow inline scripts (which is often required) use sha256- or nonce- features of CSP to allow only trusted inline code blocks.
- Make your CSP as fine-grained as possible. So, an extreme case: instead of allowing all scripts from self, explicitly list URIs of those scripts that you do load and approve. While I realize this is not very practical is real life, just try to make the CSP whitelist not too broad. </ol>