Using Content Security Policies (CSP) for Frontend Security

Using Content Security Policies (CSP) for Frontend Security

The separation between the frontend and backend becomes slimmer every day. As a result, the frontend carries the same amount of responsibilities as the backend, which opens the door for complicated attacks. Therefore the importance of frontend security is at an all-time high.

The Content Security Policy (CSP) has become one of the forefronts in a developer's arsenal against frontend security threats. First, we will dive into the basics and later go through the implementation of security controls.

What is Content Security Policy (CSP)?

Content Security Policy is an HTTP response header that provides an added layer of security for web applications to detect and mitigate Cross-Site Scripting and Data Leakage attacks. It is fully backward compatible with all commonly-used web browsers such as Google Chrome, Firefox, Microsoft Edge, etc.

However, the browsers that do not support it will ignore the policies set within CSP and default to the standard same-origin policy for the web content.

Threats mitigated using Content Security Policy

There are several attacks we can mitigate using CSPs. Let's look into them in detail for a better understanding.

Mitigating Cross-Site Scripting Attacks

Cross-Site Scripting (XSS) attacks exploit the web browser's trust in the content received from a server. As a result, malicious scripts can be executed in the victim's browser, even when it's originating from a spoofed source.

CSP allows developers to define the domains that the web browser should consider legitimate sources of executable scripts. Once configured, the web browser will only execute scripts loaded in source files received from these domains and ignore all other scripts, including inline and event-handling HTML attributes.

Mitigating Man-In-The-Middle Attacks

Another feature of CSP is that it allows developers to specify which protocols they can use for client-server communication. For example, this feature is helpful to force all content from a specific web server must be loaded using HTTPS, thus reducing the possibility of an attacker reading the contents while the information is in transit.

Configuring CSP For Your Web Application

Configuring CSP involves setting up the "Content-Security-Policy" HTTP response header in a web page. It restricts the web browser from loading resources from locations other than the ones defined in the CSP configuration.

Content-Security-Policy: policy

Writing A Content Security Policy

When writing a CSP, one or more of the following policy directives must be specified while defining the policy.

  • Your policy should include a default-src policy directive; this becomes the default fallback for other resource types not specified.
  • The default-src or script-src directive is required to prevent inline scripts and the eval() function from executing.
  • The default-src or style-src directive is required to restrict inline styles from being applied from a <style> HTML element or a style attribute.

There are specific directives defined for various items you may find within a web page. Policy directives for each particular item are mandatory. Items include separate directives for fonts, frames, images, audio and video media, scripts, and workers. A complete list of the directives is available here.

Common Use Cases For Implementing CSP

Example 1

Using the following policy, you can only allow content coming in from the site's origin. However, this does not include subdomains:

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

Example 2

You can use this policy when you want content from a trusted domain and all its subdomains. The domain does not have to be the same as the one that of the CSP:

Content-Security-Policy: default-src 'self' trusted.com *.trusted.com

Example 3

You may use the following policy to allow include images from any origin but restrict audit and video to trusted domains, and all scripts will run from a trusted domain hosting the scripts:

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

Example 4

You can use the following policy to ensure that all content is loaded using TLS to prevent a Man-in-the-middle attack:

Content-Security-Policy: default-src https://onlinebanking.bank.com

Example 5

The following policy allows HTML from the same origin and a specific domain, images loaded from anywhere but not JavaScript or other potentially dangerous content:

Content-Security-Policy: default-src 'self' *.bank.com; img-src *

Testing Your Policy

You can use the following method to configure the CSP policy in report-only mode. This way, the policy isn't applied, but the browser will notify you of any violations.

To configure your policy in report-only mode, you can use the Content-Security-Policy-Report-Only HTTP header.

Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/

If you still want to receive reports but also want to enforce a policy, use the Content-Security-Policy HTTP header with the report-uri directive:

Content-Security-Policy: default-src https:; report-uri /csp-violation-report-endpoint/

Sample Violation Report

The example below illustrates a CSP policy directive disallowing everything but stylesheets from cdn.example.com.

Content-Security-Policy-Report-Only: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports

The signup.html page hosted on http://example.com/signup.html is as follows:

<!DOCTYPE html>
<html><head><title>Sign Up</title>
      <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    ... Content ...
  </body>
</html>

Since the signup.html page is requesting the style.css stylesheet from example.com, the CSP policy which is applied would block this request and send the following violation message back as a POST request back to http://example.com/_/csp-reports.

{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri  /_/csp-reports",
    "disposition": "report"
  }
}

And that's it for CSP for frontend security.

Share this post