Content Security Policy (CSP)


Overview

Content-Security-Policy (CSP) allows developers to tell the browser what client-side code can run in the browser. CSP may stop attacks that hackers launch against users of vulnerable web sites. These client-side code injection and click-jacking attacks take advantage of users using a vulnerable web application.

CSP protects sites by whitelisting which client-side source code files are allowed to execute. For this reason, except for HTML, all non-HTML client-side source code must be written in files rather than mixed the HTML. Otherwise, CSP has to effectively be disabled to allow the "unsafe inline" code to run or more complex "code hashes" or other identifiers have to be used to identify "friendly" code.

CSP does not patch vulnerabilities but may block certain attacks which may give developers time to issue patches. CSP also includes a reporting feature that can notify when CSP blocks. These reports can alert a suitably savvy developer that is auditing the reports that the site has a vulnerability.

CSP requires the following for maximum effectiveness.
  1. All non-HTML client-side source code must be written in files rather than mixed the HTML. Otherwise, CSP has to effectively be disabled to allow the "unsafe inline" code to run. Otherwise, be prepared to use code identifiers such as hashes to identify safe source code
  2. The CSP policy has to be declared in any HTTP response that contains HTML
  3. The CSP reporting feature must be enabled
  4. The CSP reporting feature requires the application provide a server to send reports
  5. The CSP reports must be audited to understand if the site contains a vulnerability allowing code injection or if the CSP configuration is incomplete or incorrect
How to use CSP
  1. Except for HTML, move any "inline" client-side source code into an appropriate source code file(s). Otherwise mark inline source code with a hash or a nonce so inline code that should be allowed to run can be identified by the browser
  2. Set up an endpoint for browsers to report CSP violations and errors
  3. Implement the report-uri directive to inform the browser where to report CSP violations and errors
  4. During regression testing, use Content-Security-Policy-Report-Only feature to have the browser report violations
  5. Implement the appropriate Content-Security-Policy directives. The following are the most common.
All sites

Generally, all sites can set default-src to 'self' indicating all client-side source code files are loaded from the same domain as the site itself. This setting protect any source code that does not have its own CSP directive. If any sources are loaded from other domains, those will be declared in the CSP policy for that type of source code file and in doing so override the default-src.
Content-Security-Policy: default-src 'self';
In addition to default-src, all sites should declare frame-ancestors policy. The value of frame-ancestors will depend on whether the site uses frames itself.

Sites that do not use frames

If the site does not contain content that requires framing, use Content-Security-Policy: frame-ancestors 'none';

Sites that use frames

If the site contains content that requires framing by the site itself, use Content-Security-Policy: frame-ancestors 'self'.

Sites that allow business partners to frame them

If the site contains content that requires framing by another site, use Content Security Policy frame-ancestor feature. For example, Content-Security-Policy: frame-ancestors https://www.example.org;

Note that multiple CSP polices can be declared in the same Content-Security-Policy HTTP header.
Content-Security-Policy: default-src 'self'; frame-ancestors 'none'
Sites using JavaScript (JS)

Sites that use JavaScript should declare from which domains the JavaScript source code files are allowed to load. Sites that load JavaScript from the same domain can set the 'self' directive. If JavaScript is loaded from other domains, include these partner domains in the directive.
Content-Security-Policy: script-src 'self' https://<partner domain>
Sites using Cascading Stylesheets (CSS)

Sites that use Cascading Stylesheets (CSS) should declare from which domains the Cascading Stylesheets (CSS) source code files are allowed to load. Sites that load Cascading Stylesheets (CSS) from the same domain can set the 'self' directive. If Cascading Stylesheets (CSS) are loaded from other domains, include these partner domains in the directive.

Content-Security-Policy: style-src 'self' https://<partner domain>

Sites using images

Sites that use images should declare from which domains the images source code files are allowed to load. Sites that load images from the same domain can set the 'self' directive. If images are loaded from other domains, include these partner domains in the directive.

Content-Security-Policy: img-src 'self' https://<partner domain>

Sites that call application programming interfaces (API)

Sites that call out to a web API should declare the domain of the API. This affects sites using XMLHttpRequest (AJAX), WebSocket, fetch(), or EventSource.
Content-Security-Policy: connect-src https://<domain of the API>
Sites using fonts

Sites that use fonts loaded via @font-face should declare from which domains the font source code files are allowed to load. Sites that load fonts from the same domain can set the 'self' directive. If fonts are loaded from other domains, include these partner domains in the directive.
Content-Security-Policy: font-src 'self' https://<partner domain>
Other directives

There are several other directives that may be applicable for some sites. Implement the applicable CSP directives

Videos


YouTubeWhat is Content Security Policy? - Part 1
YouTubeWhat is Content Security Policy? - Part 2
YouTubeWhat is Content Security Policy? - Part 3
YouTubeWhat is Content Security Policy? - Part 4
YouTubeWhat is Content Security Policy? - Part 5
YouTubeContent Security Policy: Script Source (script-src)
YouTubeContent Security Policy: Frame Ancestors
YouTubeHow to Set HTTP Headers Using Apache Server
YouTubeCheck HTTP Headers with cURL
YouTubeHow to Check HTTP Headers (Command Line)
YouTubeHow to Check HTTP Headers from Browser
YouTubeHow to Enable Apache Mod-Headers
YouTubeCross-Site Scripting: Part 1- What is Reflected XSS?
YouTubeCross-Site Scripting: Part 2 - What is DOM-based XSS?
YouTubeCross-Site Scripting: Part 3 - What is Persistent XSS?
YouTubeCross-Site Scripting: Part 4 - How Output Encoding Stops XSS
YouTubeCross-Site Scripting: Part 5 - How to Test Output Encoding
YouTubeHow to Enable Apache Mod-Headers