Hello my dear friends.
Today we will talk about Content Security Policy and how it can help your to improve security of your web applications.
What is Content Security Policy?
Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement or distribution of malware.
How to use it
Instead of blindly trust to everything that a server delivers, CSP defines the
Content-Security-Policy HTTP header that allows you to create a whitelist of sources of trusted content, and instructs the browser to execute or render only resources from those sources. Even if an attacker can find a hole through which to inject script, the script won’t match the whitelist, and therefore won’t be executed.
For example, if we trust
cdn.example.com to deliver valid code, and we trust ourselves to do the same, let’s define a policy that only allows script to execute when it comes from one of those two sources:
This head can contain such directives:
|style-src||'self' css.example.com||Defines valid sources of stylesheets|
|img-src||'self' img.example.com||Defines valid sources of images|
|connect-src||'self'||Applies to XMLHttpRequest (AJAX), WebSocket or EventSource. If it is not allowed, the browser emulates a 400 HTTP status code|
|font-src||font.example.com||Defines valid sources of fonts|
|object-src||'self'||Defines valid sources of plugins, eg <object>, <embed> or <applet>|
|media-src||media.example.com||Defines valid sources of audio and video, eg HTML5 <audio>, <video> elements|
|child-src (old version frame-src)||'self'||Defines valid sources for loading frames|
|sandbox||allow-forms allow-scripts||Enables a sandbox for the requested resource similar to the iframe sandbox attribute. The sandbox applies a same origin policy, prevents popups, plugins and script execution is blocked. You can keep the sandbox value empty to keep all restrictions in place, or add values: allow-forms allow-same-origin allow-scripts, and allow-top-navigation|
|report-uri||/report||Instructs the browser to POST a reports of policy failures to this URI. You can also append "-Report-Only" to the HTTP header name to instruct the browser to only send reports (does not block anything)|
All of the directives that end with “-src” support similar values known as a source list. Multiple source list values can be space seperated with the exception of “*” and “none” which should be the only value.
|*||img-src *||Wildcard, allows anything|
|'none'||object-src 'none'||Prevents loading resources from any source|
|'self'||script-src 'self'||Allows loading resources from the same origin (same scheme, host and port)|
|data:||img-src 'self' data:||Allows loading resources via the data scheme (eg Base64 encoded images)|
|domain.example.com||img-src img.example.com||Allows loading resources via the data scheme (eg Base64 encoded images)|
|*.example.com||img-src *.example.com||Allows loading resources from the any subdomain under example.com|
|https:||img-src https:||Allows loading resources only over HTTPS on any domain|
|'unsafe-inline'||script-src 'unsafe-inline'||Allows use of inline source elements such as style attribute, onclick, or script tag bodies (depends on the context of the source it is applied to)|
As you can see we can combine all this values for “Content Security Policy” header and create most flexible rule for our app. Let’s create a little example. I am using Rails app with global gem to make it work with “Content Security Policy”. First I create global yml file with configuration (
default_headers inside rails app (
After restarting of the Rails app you should see “Content Security Policy” header in any HTTP response from your app. If someone will try to inject JS code in your app (
onclick in link), it will get such JS error:
To prevent this type of attack, you can use Subresource Integrity browser technology. The website author includes an
integrity attribute. If the values match, the resource is loaded. Otherwise, the browser refuses to load the resource. Example:
If you are using Rails with sprockets-rails gem (version >= 3), you can add
integrity key to your
More info about Subresource Integrity you can read in this article.
CSP is designed to be fully backward compatible; browsers that don’t support it still work with servers that implement it, and vice-versa. Browsers that don’t support CSP simply ignore it, functioning as usual, defaulting to the standard same-origin policy for web content. If the site doesn’t offer the CSP header, browsers likewise use the standard same-origin policy.
As you can see in this table, CSP have good support for major browsers. Internet Explorer 10-11 and Edge have partial support for CSP via the
X-Content-Security-Policy header, but even then they only appear to support the optional “sandbox” directive. More info on caniuse.
Content Security Policy can provide the additional security layer for your apps against XSS and data injection attacks (XSS is in third place in the ranking of the key risks of Web-based applications under the 2013 OWASP).
That’s all folks! Thank you for reading till the end.