📜 ⬆️ ⬇️

Improving network security with Content Security Policy



Content Security Policy (CSP) is a security mechanism that can be used to protect against content injection attacks, such as cross-site scripting (XSS). CSP describes secure sources for loading resources, sets rules for using embedded styles, scripts, and dynamic JavaScript evaluation — for example, using eval. Downloading from non-whitelist resources is blocked.

Operating principle


The CSP is now a candidate for recommendations from the W3C consortium . To use the policy, the page must contain an HTTP Content-Security-Policy header with one or more directives that are whitelists. Version 1.0 supports the following directives:


Default default-src lists the allowed default sources for the remaining directives. If any directive is not specified in the header, the policy is applied according to the default-src list.
')
For all directives, the following rules apply:


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

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

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



By default, CSP restricts the execution of JavaScript by disabling embedded scripts and dynamically evaluating code. In combination with white lists, this allows you to prevent content injection attacks. For example, an XSS attack using an inline script tag:



Loading external scripts that are not included in the CSP will also be stopped:



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

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 and style-src contain the keyword self , and script-src and style-src contain the domain http://cdn.example.com :

 Content-Security-Policy: default-src 'self'; style-src 'self' http://cdn.example.com; script-src http://cdn.example.com; 

If you need to specify hosts to download data, then you need to specify the data: img-src 'data'; keyword data: img-src 'data'; .

In addition to domain lists, the script-src and style-src directives support the keywords unsafe-inline and unsafe-eval .


Browser Support


Currently, most browsers and their versions already support CSP 1.0 . IE distinguished itself again: in 10 and 11 versions, only partial support was provided with the X-Content-Security-Policy header. Apparently, only the optional sandbox directive is supported.

Receive CSP Abuse Reports


As already mentioned, reports of all security policy violations are logged in the browser console. This is convenient while you are developing the site, but after deployment you need a more practical way to get reports on violations. For this, you can use the directive report-uri . Every time a CSP violation is registered, the directive sends an HTTP POST request to the specified address. The request body contains a JSON object, which contains all the necessary details.

Suppose we have such a CSP:

 Content-Security-Policy: default-src 'self'; report-uri: https://example.com/csp/report; 

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

 { "csp-report": { "blocked-uri:" "http://ajax.googleapis.com" "document-uri:" "http://example.com/index.html" "original-policy": "default-src 'self'; report-uri http://example.com/csp/report" "referrer:" "" "violated-directive": "default-src 'self'" } } 

Content-Security-Policy-Report-Only


If you are not sure yet whether it is worth implementing CSPs, you can try using Content-Security-Policy-Report-Only instead of the Content-Security-Policy header. In this case, the CSP will log violations without any blocking of resources. You can even use both Content-Security-Policy and Content-Security-Policy-Report-Only at the same time, running around certain configurations to the second.

Spelling title


The HTTP header can be written directly in the configuration files on the server:

 # Apache config Header set Content-Security-Policy "default-src 'self';" # IIS Web.config <system.webServer> <httpProtocol> <customHeaders> <add name="Content-Security-Policy" value="default-src 'self';" /> </customHeaders> </httpProtocol> </system.webServer> # 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, PHP , Node.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://*.facebook.com http://*.facebook.com https://*.fbcdn.net http://*.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' https://*.akamaihd.net http://*.akamaihd.net *.atlassolutions.com; style-src * 'unsafe-inline'; connect-src https://*.facebook.com http://*.facebook.com https://*.fbcdn.net http://*.fbcdn.net *.facebook.net *.spotilocal.com:* https://*.akamaihd.net wss://*.facebook.com:* ws://*.facebook.com:* http://*.akamaihd.net https://fb.scanandcleanlocal.com:* *.atlassolutions.com http://attachment.fbsbx.com https://attachment.fbsbx.com; 

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:; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVZXO2LGOQ%3D%3D%3D%3D%3D%3D&ro=false; 

Here https: is written everywhere, that is, SSL is enforced.

CSP Level 2


Also a candidate for recommendation . The following innovations are made in CSP Level 2:


There are two new fields in JSON contained in the abuse reports:


Also in CSP Level 2, it became possible to resolve inline scripts and styles using nonce values ​​and hashes.

Nonce is a string variable generated randomly 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 first need to generate them on the server and include them in the CSP header, respectively, in the style-src or script-src directives. 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 (base64) algorithm.

 Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-V8ghUBat8RY1nqMBeNQlXGceJ4GMuwYA55n3cYBxxvs='; 

During page rendering, the browser for each inline script calculates hashes and compares with those listed in the CSP. The above hash allows you to run the script:

< sript >console.log('Hello, SitePoint');< /sript >

Please note that spaces do matter, so these scripts will not be executed:

<sript> console.log('Hello, SitePoint');</sript>

<sript>console.log('Hello, SitePoint'); </sript>

Finally


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

Source: https://habr.com/ru/post/271575/


All Articles