A Content Security Policy, or CSP, is an additional layer of security delivered via an HTTP Header, similar to HSTS technology. This policy helps prevent various kinds of attacks, including Cross-Site Scripting (XSS) and other code injection attacks by defining content sources that are approved, therefore allowing the browser to load them.
Without a Content Security Policy, the browser will just load all files on the page without considering their source, which could be a harmful site. That puts the site and visitors at higher risk of malicious activity.
What browsers support Content Security Policies?
All major browsers offer full or partial support for Content Security Policies.
However, in the event that someone’s using a really old browser, the Content Security Policy won’t be applied. Content Security Policies are backward compatible which means that older browsers are still able to view webpages that are protected by said Content Security Policies, and vice-versa.
What directives are supported in a Content Security Policy?
There are many directives available to website owners who want to implement a Content Security Policy. A server can also define which directives within its own security header. The following list outlines the directives available for use along with their description:
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 a policy violation
The above directives can all be used when Creating a Content Security Policy, depending on what you want to accomplish.
How to Create a Content Security Policy
Considering the number of directives in the list in the above section, there’s a lot of options available for Administrators to create their Content Security Policy. A CSP format is defined as Content-Security-Policy: policy
. The following shows a few examples for configuring your Content-Security-Policy
header.
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
The default-src
directive set to https:
will allow the browser to load the resource from any origin using https://
.
Content-Security-Policy: default-src https:
This CSP allows for any resource to be loaded from the current domain as well as any subdomain of example.com
(both HTTP and HTTPS).
Content-Security-Policy: default-src 'self' *.example.com
The following CSP makes use of the frame-ancestors
the 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'
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
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.
You can also use this really cool tool called cspisawesome.com to easily create a CSP specific to your site’s needs.
Testing Your New Content Security Policy
Once you’ve determined how you want to define your Content Security Policy, it’s time to put it to the test and make sure it works as described on the tin.
For testing purposes, instead of defining your CSP as Content-Security-Policy:
you may use Content-Security-Policy-Report-Only:
instead. This won’t enforce the policy rules on the web page but 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 & Litespeed 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.
When you’re 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 you’ve got your Content Security Policy properly configured and in place, your site will be much less vulnerable to XSS attacks. However, in the event that the Content Security Policy does trigger an unwanted action, the report-uri directive can be utilized to keep track of any activity that is in violation of the Content Security Policy.
Using this directive, the browser will post a JSON formatted report to the defined URL of your choosing. This directive can be appended to the end of your Content Security Policy like this:
Content-Security-Policy: "default-src 'none'; script-src https://example.com; report-uri https://report.example.com"
When a report is triggered, it 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"
}
}
Once Reporting is properly configured, you will be able to keep a closer eye on which sources are in violation of your new Content Security Policy.
If you enjoyed this tutorial, then you’ll love our support! All ChemiCloud’s hosting plans include 24/7 support from our amazing support team. Check out our Web hosting plans and have your website migrated today!