Understand Content Security Policy (CSP) in 10 Minutes

A cartoon image depicting security

Are your web applications truly secure? Unsure? It’s time you became familiar with Content Security Policy. This under-utilised security standard can make or break the resilience of your applications. But what is CSP really about, and how can it be leveraged in frontend development? In this article, we will answer these questions and help understand how to effectively use CSP in your work.

Table of Contents

  1. Introduction
  2. What is Content Security Policy (CSP)?
  3. How Does Content Security Policy Work?
  4. How is Content Security Policy Implemented?
  5. Available CSP Directives
  6. What Types of Attacks Can CSP Prevent?
  7. How is CSP Relevant for a Frontend Developer?
  8. Final Thoughts

Introduction

The landscape of the web is a vibrant place filled with data exchanges and user interactions. One of the foundations of this environment is HTTP communication. Yet, it is open to many threats and vulnerabilities.

Two common dangers are Cross-Site Scripting (XSS) and Data Injection attacks. In an XSS attack, a harmful script is inserted into a trusted website and then runs in an unsuspecting user’s browser. This can lead to unauthorised access, data theft, or damage to the website. In a Data Injection attack, an attacker inserts harmful data or code into a website with the goal of tricking the system or disrupting its operation.

These are just examples; many other threats are lurking out there (we’ll discuss some of them later in this article.) But we are not defenceless! There are ways to protect our websites, and one of them is Content Security Policy (CSP).

What is Content Security Policy (CSP)?

Before we dig into the technical details, let’s take a moment to understand what CSP actually is.

In short, Content Security Policy (CSP) is a mechanism that enables developers to define and enforce rules for controlling which external sources of content are allowed to be loaded and executed on a web page, imposing stronger limitations on resource origins.

I bet that abstract definition didn’t really help you to understand anything, so let’s use an analogy.

Imagine for a moment that your website is a country. Every script, image, and stylesheet that resides on your site is a citizen of this digital nation, each playing its role in creating a rich and dynamic user experience. However, like any country, your website needs laws to maintain order and security, to prevent chaos, and to protect its citizens from external threats. This is where Content Security Policy comes into play.

In this digital country, your server takes on the role of the government, drafting and passing laws that govern the behaviour of its citizens. These laws, or in the case of CSP, a set of directives, dictate where scripts, images, and other elements can originate from. They define the trusted sources from which these assets can be loaded, providing the framework of rules for your website.

But, setting these rules isn’t enough on its own; enforcement is key to maintaining order and security. Here comes the browser: your website’s police force. Once the server sets the CSP rules, the browser takes charge of upholding them. It carefully checks every request and piece of content, ensuring they adhere to the rules set by the server. If any content tries to breach these rules, the browser blocks it, much like a police officer would prevent illegal activities.

Content Security Policy, therefore, is a key element of web security. A standard designed to safeguard your website against potential threats like XSS attacks, clickjacking, and others. By implementing a robust CSP, you are laying down the law for your digital nation, creating a safer and more secure environment for all your website’s assets.

How Does Content Security Policy Work?

Now that you have an idea of what Content Security Policy is, let’s see how it works.

Imagine an e-commerce website, let’s call it TrendyShop.com, which serves as a digital marketplace for all things fashion. On this site, users can easily search for their desired products using a search box. A user might, for instance, input “shirt” into the search field. Eager to assist, the website immediately incorporates this query directly into the HTML response, without due validation or encoding. The user’s search query is then echoed back on the results page as: “You searched for: shirt.”

One day, a crafty attacker stumbles upon TrendyShop.com and spots the oversight in sanitising search queries. Sensing an opportunity, the attacker crafts a malicious URL with a hidden JavaScript payload. The URL takes this form:

https://trendyshop.com/search?query=<script>/* here comes a script which steals a session cookie */</script>

The attack unfolds in the following sequence:

  1. The attacker devises a social engineering strategy, masquerading as a TrendyShop.com promotional email. The message tempts users with a limited-time offer: “Exclusive 50% discount on your next purchase! Click here to claim your offer!” Hidden in the innocent-looking link is the attacker’s malicious URL.
  2. An unsuspecting user, tempted by the promise of a good deal, clicks on the link. As the website processes the URL, it unwittingly incorporates the search query into the search results page without appropriate sanitization. This action prompts the JavaScript payload to execute within the user’s browser, capturing the authentication session cookie in the process.
  3. Armed with the stolen session cookie, the attacker can now impersonate the user and perform actions on their behalf on TrendyShop.com.

This scenario is a classic example of a reflected XSS attack, where an attacker leverages a vulnerability in how user input is processed and reflected back to the user without appropriate sanitization. By injecting a malicious script into a URL, the attacker manipulates this weakness to execute arbitrary code in the user’s browser.

How Content Security Policy Could Have Saved TrendyShop.com from an XSS Attack

Content Security Policy (CSP) could have been a game-changer for TrendyShop.com had it been properly implemented. CSP would have set rules for content interaction and prevented the XSS attack.

Here’s how it could work:

  1. Let’s say that TrendyShop.com has implemented CSP and it includes a rule script-src 'self'. This rule tells the browser that only scripts originating from the website’s own domain (TrendyShop.com in this case) should be trusted and executed. Any scripts from external or inline sources would be blocked.
  2. When the attacker tricks the user into clicking the malicious link, the browser still receives the payload script embedded in the URL. But, because of the CSP rule, the browser recognizes that the script isn’t coming from a trusted source (i.e., it’s not coming from TrendyShop.com). So, it refuses to execute the script, effectively preventing the XSS attack.

It’s important to note, though, that CSP is not a one-size-fits-all solution and isn’t the only line of defence against XSS and other security threats. Proper input validation and output encoding also play crucial roles in a robust web security strategy. Good website security is implemented in layers, and CSP is just one of such layers.

How is Content Security Policy Implemented?

So we have discussed what CSP can do for website security and how it works, but you are probably wondering how it can be technically implemented. It is actually quite simple.

Content Security Policy (CSP) is implemented through the Content-Security-Policy HTTP response header. The structure of the CSP header comprises directives and sources. Directives define the types of resources and actions the policy governs, while sources specify the locations (URLs) from where these resources can be safely loaded.

The general structure of a CSP header looks like this:

Content-Security-Policy: directive-1 source-1 source-2; directive-2 source-3;

This policy allows content for directive-1 to be loaded from source-1 and source-2, and content for directive-2 to be loaded from source-3.

And for a more concrete example, here is what possible implementation of the CSP header for our TrendyShop.com might look like:

Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; report-uri /csp-violation-report-endpoint;

Let’s break this down:

  • default-src 'self' - This directive is setting the default sources to the same origin. This means that by default, all types of content can only be loaded from TrendyThreads.com itself.
  • script-src 'self' - Allows JavaScript to be loaded only from the website’s own domain. Any scripts from external or inline sources would be blocked.
  • connect-src 'self' - Defines valid endpoints for fetch, XMLHttpRequest, WebSocket, and EventSource connections. This directive restricts those connections to the same origin.
  • img-src 'self' https://trusted.cdn.com; - Allows images to be loaded from the website’s own domain and a trusted CDN.
  • style-src 'self' 'unsafe-inline' - This directive allows styles to be loaded from the website’s own domain. The 'unsafe-inline' allows inline styles, which can be needed for dynamically updating styles with JavaScript.
  • report-uri /csp-violation-report-endpoint - Specifies a URL where the browser will send reports about policy violation attempts.

This is just a basic example, and it’s important to understand that crafting a CSP should be done considering all types of content and sources that the website needs to function properly. The set of directives and sources would be different for each site and must be adapted according to its specific requirements and infrastructure.

Available CSP Directives

Now, let’s take a look at the available directives that you can use in a CSP. There are quite a few of them, you can find a complete list on MDN, but here are the most commonly used ones:

  • default-src - this is the fallback directive for when other directives are not explicitly defined
  • script-src - this directive specifies valid sources for JavaScript
  • style-src - this one is for valid CSS sources
  • img-src - this directive sets valid image sources
  • connect-src - defines valid endpoints for fetch, XMLHttpRequest, WebSocket, and EventSource connections
  • font-src - specifies valid font sources
  • object-src - defines valid sources for plugins, like <object>, <embed>, or <applet>
  • media-src - defines valid sources for loading media using the <audio> and <video> elements
  • frame-src - sets valid sources for nested browsing contexts loading using <frame> or <iframe>
  • sandbox - this directive applies restrictions to a page similar to the restrictions applied by the <iframe sandbox> attribute
  • report-uri / report-to - these directives specify where to send reports about policy violations

What Types of Attacks Can CSP Prevent?

Content Security Policy (CSP) can help prevent or mitigate several types of attacks on a website. Here is a list of common attacks it can help address:

  1. Cross-Site Scripting (XSS): XSS attacks involve injecting malicious scripts into a website, which are then executed by unsuspecting users. CSP can block or limit the execution of inline scripts and restrict the sources from which scripts can be loaded, reducing the risk of this kind of attack.
  2. Data Injection: By controlling the allowed sources for loading external content, such as images, fonts, or stylesheets, CSP can prevent attackers from injecting unauthorised content into a website.
  3. Clickjacking: Clickjacking attacks attempt to trick users into clicking on hidden or disguised elements on a webpage, leading to unintended actions or malicious operations. CSP can mitigate clickjacking by preventing the rendering of the website within a frame or by limiting the sources that can frame the website.
  4. Mixed Content Attacks: Insecure mixed content refers to a webpage served over HTTPS but containing elements (e.g., images, scripts) loaded over HTTP. This can compromise the integrity and security of the website. CSP can enforce the use of secure sources (HTTPS) for all content, helping to prevent mixed content attacks.
  5. Content Injection: CSP can guard against content injection attacks, where an attacker tries to modify the content of a website, such as replacing legitimate resources with malicious ones. By specifying the allowed sources for each content type, CSP ensures that only authorized content is loaded.
  6. Data Exfiltration: CSP can help prevent data exfiltration attacks by restricting the domains or endpoints to which sensitive data can be sent. By controlling the sources allowed for making network requests, CSP can limit the potential for data leakage.
  7. Remote Code Execution: CSP can reduce the risk of remote code execution attacks by limiting the sources from which scripts can be loaded or executed.

How is CSP Relevant for a Frontend Developer?

As a frontend developer, while you’re not directly setting HTTP headers - that’s the backend’s job - you play a role in advocating for, shaping, and testing Content Security Policy settings. This makes you an essential part of the defence against various web-based security threats.

Firstly, in the battle against XSS attacks, you’re in the best position to identify potential security risks and to communicate these to the backend team who can set up appropriate CSP headers. This collaborative effort can effectively mitigate the risk of XSS, blocking unauthorised scripts before they have a chance to run on your site.

Secondly, while you’re developing a web page and juggling numerous resources – scripts, styles, fonts, and images – it’s you who knows best where these resources are loaded from and which ones are trusted. By working in tandem with your backend colleagues, you can help formulate a CSP that only permits resources from trusted sources to be loaded, reducing the risk of resource hijacking.

The need for collaboration is especially important when things don’t work as expected due to the CSP in place. It’s not uncommon for issues to arise in local, development, or staging environments when the CSP rules don’t account for specific aspects of those environments. Your understanding of CSP is critical here. It empowers you to effectively investigate issues, understand the root causes, and propose modifications to the backend team.

Lastly, CSP also allows you to influence the behaviour of the page in terms of navigation, form submission, and blocking mixed content (HTTP and HTTPS), among other things. Having a say in these settings affects your ability to deliver a secure and seamless user experience.

So, even though as a frontend developer you don’t directly implement CSP, your role in its application is vital. Understanding CSP, driving its implementation, and being able to troubleshoot issues places you at the forefront of web application security.

Final Thoughts

Content Security Policy is a powerful weapon in your web developer’s arsenal. A well-configured CSP can make a big difference to your site’s security and provide a safer environment for your users. The beauty of CSP lies in its ease of implementation, paired with flexibility and scalability. But remember to strike a balance between being too restrictive and too permissive when setting your directives, be pragmatic in your decisions.

Also remember that CSP isn’t a set-and-forget solution, you must review and update the policy regularly. As a website evolves, new features might be added, new third-party scripts might be introduced, or new types of content may need to be handled. It’s all too easy to forget that each of these changes may require an update to the CSP. Leave the CSP out-of-date, and your website’s security can be compromised, while you will have a false sense of security, believing in the protection of your CSP.

Finally, as powerful as CSP is, it shouldn’t be used in isolation. It is not a magic wand that can instantly secure your website. It must be part of a layered security strategy that includes proper input validation, output encoding, secure handling of user data and other measures necessary for your specific case.

Implementing a strong Content Security Policy is a significant step in securing any website. So wield this tool wisely, making the web a safer place for everyone.

Ikona Smiley Follow Us!
Logo FacebookLogo Twitter

Copyright 2022 – 2023 ©
Michał Wilkosiński CONIFER MEDIA
All rights reserved