Here’s a few quick notes from GitHub security engineer Neil Matatall’s talk at A Midsummer Night’s Con 2020, a virtual event hosted by Absolute AppSec.
In this talk, Neil gives an overview of Content Security Policy (CSP): how it works, how to go from no CSP to a solid CSP, and an explanation of strategies to create an effective and dynamic policy including code samples taken directly from the GitHub codebase.
Generate a Baseline CSP
Browser extensions like Caspr for Chrome and Laboratory by Firefox can help.
Reporting
Making CSP violation reporting useful is actually hard in practice. A primary reason for this is many visitors to your site may have random extensions that inject content into pages that violate your CSP, their browser may be compromised, etc.
CSP reporting can be useful if you can restrict it a set of users who you know will have sane browser settings; for example, your employees.
Get Started, then Improve Over Time
You won’t be able to create a perfect policy from scratch at the beginning. They key is just to get started, even if your initial CSP is quite permissive. Then, ratchet up the restrictiveness over time.
This gives you some initial protection, and prevents the introduction of new code that makes your security posture worse.
Neil walks through a few examples of CSP policies and what cases they’d help prevent.


unsafe-inline
and unsafe-eval
can be quite difficult on large existing codebases, but are huge wins for security.

strict-dynamic
strict-dynamic
can make CSP deployments easier, and can allow you to allow a
enable specific scripts via a provided nonce or hash. Overview demo
page.
From
MDN:
strict-dynamic
“specifies that the trust explicitly given to a script present
in the markup, by accompanying it with a nonce or a hash, shall be propagated to
all the scripts loaded by that root script.”
How GitHub Implements CSP
Since CSP is just a response header, you can have different controllers, and even different endpoints on the same controller return different CSPs.

CSP_EXCEPTIONS
), or this can be done for one endpoint, for example, related to a specific feature.

And set for static files as well:
