Content-Security-Policy (CSP) Versions 2.0 & 3.0

Content Security Policy is still very dynamic in its definitions. Reporting is handled differently and new directives are being added, some are being renamed, and others the definition is being refined.

Some notable additions to the original:

Frame-Src & Child-Src – In CSP v1 frame-src defined what domains your site is allowed to frame. This is to prevent an attacker from creating an iframe which references a site they control for example. CSP2 renamed child-src to frame-src and CSP3 will be bringing back both child-src and frame-src, plus adding worker-src:
worker-src – If not defined, will defer to child-src. Defines the approved sources for Worker, SharedWorker, or ServiceWorker scripts.
frame-src – In CSP 3 if not defined, will defer to child-src. Defines the approved sources for FRAME and IFRAME sources
child-src – Defines sources for frames (if frame-src is not defined) and workers (if worker-src is not defined). Falls back to default-src if not defined.

Frame-Ancestors – Frame-Ancestors is a new directive used to determine what sites (including your own) are allowed to frame this page. It works similar to the HTTP header X-FRAME-OPTIONS except you can enumerate the domains that are allowed instead of just none or self.’

Nonces – Nonces are once-per-page-load values in the header that allow elements with a matching “nonce” property to execute the code. Dropbox has used this along with some other creative methods to move away from unsafe-inline scripts [1]

Strict-Dynamic – New in CSP3.0, we’ll discuss this and methods of backward compatibility next week.

Common Problems Implementing CSP

Convincing DevOps to add this header is pretty easy, making sure it doesn’t cause problems can be more difficult.

Too Many Violation Reports – Reporting is a very powerful feature in blocking mode or not and the reports are hidden from the user (except for a JavaScript console message available using debugging tools) and asynchronously sent. However they are not free as far as browser resources are concerned, and too many may result in a slight degraded UI experience.

Inline Scripts – Many developers add JavaScript directly in the web page using <script></script> tags. This requires either moving all these scripts to JS files, the use of nonces in the script tag, or allowing them using the ‘unsafe-inline’ directive. Moving all the scripts would be the best way, but may lead to an enormous amount of work. Using nonces would be the next best alternative, but requires a dynamic CSP header (which contains the nonce value), making that value available to the template engine, and modifying the code templates to include the nonce variable. Usually, teams will allow ‘unsafe-inline’ until one of these is complete.

Too Many Sources – At tCell, and in a few other instances, we’ve seen so many domains get whitelisted that all of the sudden the reverse proxy (Nginx or other) starts returning an error such as 502 without many details until you dig into the proxy logs. There is a maximum header size many reverse proxies impose so be sure you’re aware of that size and the size of your CSP header length. Plus if you’re trusting that many sources maybe you should condense them!

Unpredictable Reports – Firefox vs Chrome, Mobile vs Desktop, There is no one specification these browsers follow. However, there is some core information that you’ll be able to gather such as blocked-URI, document-URI, original policy, and violated-directive. You may still also want to collect information from other browsers but do not depend on it. Various browsers may also require the data to be modified/normalized when collected. [2]

CSP Browser Graph


If you’re looking for more information on how and why to get started with CSP, check out “Top 3 Reasons to Get Started with Content Security Policy“. There are tons of resources from beginner to advanced.