Content Security Policy (CSP) is a security layer that can help you detect and mitigate Cross Site Scripting (XSS) and data injection attacks. If your web application displays and stores custom HTML/CSS from user input, then you most certainly need a good filtering method that will remove any Inline JS (<script>
tags, onclick
from <a>
links, etc).
CSP defines the Content-Security-Policy
HTTP header that allows you to whitelist sources of trusted content, and instructs the browser to execute or render on your website only resources from those sources. So even if an attacker finds a hole through which to inject JS, the script won’t match the whitelist, and therefore won’t be executed.
example:, if we use CDN and trust cloudflare.net
to deliver valid code, let’s define a CSP that only allows scripts to execute when they come from one of those two sources:
Content-Security-Policy: script-src 'self' cloudflare.net
Here is a table showing the most commonly used CSP directives:
Directive | Example | Description |
---|---|---|
default-src | ‘self’ cloudflare.net | default policy for loading ALL content (JS, Images, CSS, Font’s, AJAX requests, Frames, HTML5..) |
script-src | ‘self’ js.cloudflare.net | valid sources of JavaScript |
style-src | ‘self’ css.cloudflare.net | valid sources of stylesheets |
img-src | ‘self’ img.cloudflare.net | valid sources of images |
connect-src | ‘self’ | Applies to XMLHttpRequest (AJAX), WebSocket or EventSource. |
font-src | font.google.com | valid sources of fonts |
object-src | ‘self’ | valid sources of plugins, eg <object>, <embed> or <applet> |
media-src | media.wpxss.com | valid sources of audio and video, eg HTML5 <audio>, <video> elements |
child-src (frame-src) | ‘self’ | valid sources for loading frames |
sandbox | allow-forms allow-scripts | a sandbox for the requested resource similar to the iframe sandbox attribute. |
report-uri | /report | instructs the browser to POST a reports of policy failures to this URI. |
Okay but is it a good practise to whitelist 3rd party websites? what if one day Cloudflare get’s compromised?
Well there is also a solution for that! 🙂 -you can use the Subresource Integrity browser technology.
What this means is that you can include an integrity attribute on all loaded JS and CSS tags where you specify the cryptographic digest of the resource being loaded from the third party. That way, every time the browser renders the page and fetches resources from Cloudflare it computes the file’s digest and compares it with the value from the integrity
attribute. If the values match, a resource is loaded, and if not, the browser will refuse to load the resource.
Example:
script src="/wp-includes/js/jquery/jquery.min.js" integrity="sha256-db9a9a37da262883343e941c3731bc67="></script>
Browser Support
Browsers that don’t support CSP simply ignore it, defaulting to the standard same-origin policy.
Header | Chrome | FireFox | Safari | Internet Explorer/Edge |
---|---|---|---|---|
Content-Security-Policy (1.0) | 25+ | 23+ | 7+ | – |
Content-Security-Policy (2.0) | 36+ | 31+ | 10+ | – |
X-Content-Security-Policy | – | 4.0+ | – | 10+ |
X-Webkit-CSP | 14+ | – | 6+ | – |
As you can see in this table, CSP have good support for major browsers. More info on caniuse.