Content Security Policy
What is a Content Security Policy?
A Content Security Policy (CSP) is an additional layer of security delivered via an HTTP header, similar to HSTS. This policy helps prevent attacks such as Cross Site Scripting (XSS) and other code injection attacks by defining content sources which are approved thus allowing the browser to load them. Without a CSP, the browser simply loads all files on a page without considering the source which could be harmful. This puts both the site and it's visitors at risk of malicious activity.
All major browsers currently offer full or partial support for Content Security Policy.
However, in the event that a user is accessing your site via an older browser, the CSP will simply not be executed. CSP security is backwards compatible meaning that older browsers are still able to to view the webpages that CSP-enabled web server deliver, and vice-versa.
Supported directives
There are multiple directives available to website owners who want to implement a content security policy. A server may also define multiple directives within a CSP security header. The following list provided by OWASP, outlines the CSP directives available for use along with a description of each.
default-src
Define loading policy for all resources type in case of a resource type dedicated directive is not defined (fallback),script-src
Define which scripts the protected resource can execute,object-src
Define from where the protected resource can load plugins,style-src
Define which styles (CSS) the user applies to the protected resource,img-src
Define from where the protected resource can load images,media-src
Define from where the protected resource can load video and audio,frame-src
Define from where the protected resource can embed frames,frame-ancestors
Specifies valid parents that may embed a page using<frame>
,<iframe>
,<object>
,<embed>
, or<applet>
.font-src
Define from where the protected resource can load fonts,connect-src
Define which URIs the protected resource can load using script interfaces,form-action
Define which URIs can be used as the action of HTML form elements,sandbox
Specifies an HTML sandbox policy that the user agent applies to the protected resource,script-nonce
Define script execution by requiring the presence of the specified nonce on script elements,plugin-types
Define the set of plugins that can be invoked by the protected resource by limiting the types of resources that can be embedded,reflected-xss
Instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standardX-XSS-Protection
header,report-uri
Specifies a URI to which the user agent sends reports about policy violation
These directives can all be used when creating your Content Security Policy depending on what you want to achieve. The following section outlines a few example policies.
How to create a Content Security Policy
As seen by the CSP directives outlined above, there are many options available for configuring a Content Security Policy on your web server. A CSP format is defined as Content-Security-Policy: policy
. The following shows a few examples for configuring your Content-Security-Policy
header.
Example 1
This CSP will allow scripts from both the current domain (defined by 'self'
) as well as https://www.google-analytics.com
.
Content-Security-Policy: script-src 'self' https://www.google-analytics.com
Example 2
The default-src
directive set to https:
will allow the browser to load resource from any origin using https://
.
Content-Security-Policy: default-src https:
Example 3
This CSP allows for any resource to be loaded from the current domain as well as any sub domain of example.com
(both HTTP and HTTPS).
Content-Security-Policy: default-src 'self' *.example.com
Example 4
The following CSP makes use of the frame-ancestors
directive which defines which sources are allowed to embed a page using <frame>
, <iframe>
, <object>
, <embed>
, or <applet>
. To allow only your site use the following.
Content-Security-Policy: frame-ancestors 'self'
Example 5
Ports can also be defined in content security policies. This example restricts resources to be loaded only from https://www.keycdn.com
using port 443
.
Content-Security-Policy: default-src https://www.keycdn.com:443
Example 6
The first part of this example default-src 'none';
tells the browser not to load any resources from any sources. While the second part script-src https://www.keycdn.com
tells the browser to allow scripts from www.keycdn.com
over https://
.
Content-Security-Policy: default-src 'none'; script-src https://www.keycdn.com
For a detailed list of examples and references, visit content-security-policy.com.
Content Security Policy testing
Once you have determined how you would like to configure your CSP security, it is time to test it to ensure it works as expected. For testing purposes, instead of defining your CSP as Content-Security-Policy:
you may use Content-Security-Policy-Report-Only:
instead. This will not enforce the policy rules on the web page but rather will simply provide you with feedback as to how the policy will react.
This example uses the following CSP. For Nginx users, this snippet is placed within the configuration file.
add_header Content-Security-Policy-Report-Only: "default-src 'none'; script-src http://wordpress.keycdn.net";
For Apache users, the following would be placed in the configuration file
Header set Content-Security-Policy-Report-Only "default-src 'none'; script-src http://wordpress.keycdn.net;"
Once this CSP has been set on your origin server, you can open up your browser's console and will see feedback based on the directives set.
Once you are happy with the results of your CSP, you can remove the Report-Only section of the header so that the Content Security Policy will be taken into affect.
CSP reporting
Now that your Content Security Policy is properly configured on your origin server, your site will be much less vulnerable to XSS attacks. However, in the event that the CSP does trigger an unwanted action, the report-uri
directive can be utilized to keep track of any activity that is in violation of the CSP. Using this directive, the browser will post a JSON formatted report to the defined URL of your choice. This directive can be appended to the end of your CSP such as:
Content-Security-Policy: "default-src 'none'; script-src https://example.com; report-uri https://report.example.com"
The report in this case will look something like this:
{
"csp-report": {
"document-uri": "https://example.com",
"referrer": "https://malicious.com",
"blocked-uri": "https://malicious.com/assets/js/xss.js",
"violated-directive": "script-src https://example.com",
"original-policy": "default-src 'none'; script-src https://example.com; report-uri https://report.example.com"
}
}
Now that you have reporting configured, you will be able to keep a closer eye on which sources are violating your Content Security Policy. Having a CSP in place is an easy way to further increase the security of your website and thus help keep your visitors safe from any harmful malicious attacks.