Synergize Network Security With Content Security Policy

Content Security Policy (CSP, content protection policy) is a security mechanism with which you can protect yourself from attacks with the introduction of content, for example, cross-site scripting (XSS, cross-site scripting). CSP describes secure sources for loading resources, sets rules for using inline styles, scripts, and dynamic JavaScript evaluations — for example, using eval. Downloading from non-whitelisted resources is blocked.

Operating Principle
CSP is now a candidate for recommendation by the W3C. To use the policy, the page must contain an HTTP header Content-Security-Policy with one or more directives, which are whitelists. In version 1.0, the following directives are supported:
  • default-src
  • script-src
  • object-src
  • style-src
  • img-src
  • media-src
  • frame-src
  • font-src
  • connect-src
The default-src default allowed sources for the remaining directives are listed. If some directive is not indicated in the header, then the policy is applied according to the list default-src.

For all directives, the following rules apply:

Used to refer to the current domain self.
In the list, URLs are separated by spaces.
If nothing is to be loaded under this directive, then it applies none. For example, object-src 'none' prohibits the download of any plugins, including Java and Flash.

The simplest example of a policy that allows loading resources of only the specified domain:

Content-Security-Policy: default-src 'self';

Attempting to download resources from other domains will be stopped by the browser and giving notification in the console:

By default, CSP restricts JavaScript execution by prohibiting built-in scripts and dynamic code evaluation. In combination with whitelisting, this helps prevent content injection attacks. For example, an XSS attack with the introduction of an inline script tag:

Downloading external scripts that are not included in the CSP will also be suppressed:

At the moment, you cannot specify paths ( in the URL list, you can only list the domains themselves ( But wildcards are supported, so you can describe all subdomains ( http://* at once.

Directives do not inherit rights from previous directives. Each directive included in the CSP header must contain a list of allowed domains/subdomains. In the following example, default-src they style-src contain the keyword self, and script-src they style-src contain the domain

Content-Security-Policy: default-src 'self';
                   style-src 'self';

If you need to specify hosts for downloading data, then you need to specify a keyword data: img-src 'data';

In addition to domain lists, directives script-src and style-src support keywords unsafe-inline and unsafe-eval.
  • unsafe-inline used to resolve inline styles and scripts style and script. This keyword also allows CSS inline attributes style, inline event handlers (onclick, onmouseover, etc.) and javascript links like a href="javascript:foobar()". CSP works on the principle of "if something is not mentioned, then it is prohibited." That is, in the absence of the keyword unsafe-inline all inline tags style and script will be blocked.
  • unsafe-eval only used in directive script-src. If this keyword is not specified, then any dynamic evaluation of the code is blocked, including use eval, the constructor of functions, and passing strings to setTimeout and setInterval.
Browser Support
Currently, most browsers and their versions already support CSP 1.0. IE excelled again: in versions 10 and 11 only partial support was provided using the header X-Content-Security-Policy. Apparently, only the optional sandbox directive is supported.

Receive CSP Violations
As already mentioned, messages about all security policy violations are logged in the browser console. This is convenient while you are just developing the site, but after deployment, you need a more practical way to get abuse reports. You can use the directive for this report-uri. Each time a CSP violation is logged, the directive sends an HTTP POST request to the specified address. The request body contains a JSON object that contains all the necessary details.

Let's say we have a CSP like this:

Content-Security-Policy: default-src 'self'; 

This means that the browser can only download resources from our own domain. But we need to use the Google Analytics service, which will try to download JavaScript from And this is a violation of our CSP. In this case, it will report-uri send a request with the following JSON:

    "csp-report": {
        "blocked-uri:" ""
        "document-uri:" ""
        "original-policy": "default-src 'self'; report-uri"
        "referrer:" ""
        "violated-directive": "default-src 'self'"

If you're not sure whether or not to implement at CSP, then you can try instead of heading Content-Security-Policy to use Content-Security-Policy-Report-Only. In this case, the CSP will record violations without any blocking of resources. You can even use the same time Content-Security-Policy and Content-Security-Policy-Report-Only.

Title Header
The HTTP header can be specified directly in the configuration files on the server:

# Apache config
Header set Content-Security-Policy "default-src 'self';"

# IIS Web.config
            <add name="Content-Security-Policy" value="default-src 'self';" />

# nginx conf file
add_header Content-Security-Policy "default-src 'self';";

Also, many programming languages ​​and frameworks allow you to add headers programmatically (for example, PHPNode.js ):

# PHP example
header("Content-Security-Policy: default-src 'self'");

# Node.js example
request.setHeader("Content-Security-Policy", "default-src 'self'");

CSP In The Wild
Let's see how CSP is implemented on Facebook:

default-src *;
script-src https://* http://* https://* http://* * * * ** ** 'unsafe-inline' 'unsafe-eval' https://* http://* *;
style-src * 'unsafe-inline';
connect-src https://* http://* https://* http://* * ** https://* wss://** ws://** http://** *;

Note the use of wildcards to describe subdomains as well as port numbers in connect-src.

And now the Twitter option:

default-src https:;
connect-src https:;
font-src https: data:;
frame-src https: twitter:;
frame-ancestors https:;
img-src https: data:;
media-src https:;
object-src https:;
script-src 'unsafe-inline' 'unsafe-eval' https:;
style-src 'unsafe-inline' https:;

They have registered everywhere here https:, that is, SSL is forcibly used.

CSP Level 2
Also a candidate for a recommendation. The following innovations are made in CSP Level 2:
  • base-uri: allows the document to manipulate the base page URI.
  • Instead frame-src it is now applied child-src.
  • form-action: allows the document to place HTML forms.
  • frame-ancestors: Regulates how to embed this document in other documents. Works as the X-Frame-Options header, which it is probably intended to replace.
  • plugin-types: allows loading specific plugins - Flash, Java, Silverlight, etc.
Two new fields have appeared in the JSON contained in the violation reports:
  • effective-directive: here is the name of the directive that has been violated.
  • status-code: HTTP status code of the requested resource. If the infringing request was not made via HTTP, then 0 is set.
Also, CSP Level 2 has the ability to allow inline scripts and styles using nonce values ​​and hashes.

Nonce is a string variable randomly generated on the server. It is added to the CSP header:

Content-Security-Policy: default-src 'self';
script-src 'self' 'nonce-Xiojd98a8jd3s9kFiDi29Uijwdu';

and in the inline script tag:

<script> console.log("Script won't run as it doesn't contain a nonce attribute"); </script> <script nonce="Eskdikejidojdk978Ad8jf"> console.log("Script won't run as it has an invalid nonce"); </script> <script nonce="Xiojd98a8jd3s9kFiDi29Uijwdu"> console.log('Script runs as the nonce matches the nonce in the HTTP header'); </script>

If you want to use hashes, you must first generate them on the server and include them in the CSP header, respectively, in the style-src or directives script-src. Before rendering the page, the browser calculates the hash of the script/style, and if it matches the specified one, then execution is allowed.

An example of a hash generated from a string console.log('Hello, SitePoint'); using the Sha256 algorithm (base64).

default-src 'self';
script-src 'self' 'sha256-V8ghUBat8RY1nqMBeNQlXGceJ4GMuwYA55n3cYBxxvs=';

During page rendering, the browser calculates hashes for each inline script and compares them with those listed in the CSP. The above hash allows you to execute the script: Note that spaces matter, so these scripts will not be executed:

< sсript >console.log('Hello, SitePoint');< / sсript >
<sсript> console.log('Hello, SitePoint');</sсript>
<sсript>console.log('Hello, SitePoint'); </sсript>

If you have experience using CSP - positive or negative - please share in the comments. It would also be interesting to learn about the non-standard tasks that you solved using CSP.



5 Steps To Protecting Your Digital Home

Document Security System To Prevent Confidential Leakage

Safe Mobile Payments And Banking Tips Hackers Hope You Don't Know