Content Security Policy

 content security policy

What is a Content Security Policy?

A content security policy, or 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.

content security policy support

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.org, 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-standard X-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 content security policy’s 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 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.

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 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. Additionally, you can use a tool called cspisawesome.com to easily create a CSP specific to your needs.

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 content security policy has been set on your origin server, you can open up your browser’s console and will see feedback based on the directives set.

content security policy feedback

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 content security policy. 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.

Leave A Comment?