DEV Community

Cover image for Web Security with Content Security Policy (CSP) and JavaScript
Ítalo Queiroz
Ítalo Queiroz

Posted on

Web Security with Content Security Policy (CSP) and JavaScript

Currently, I work for a major educational portal in England. Since we host numerous articles, books, and case studies, security is essential for us and, most importantly, for our customers who use the platform for research, purchasing new articles, and studying. Ensuring that our users are protected against attacks such as Cross-Site Scripting (XSS) is a top priority. To mitigate this risk, one of the most effective mechanisms is Content Security Policy (CSP), a powerful feature that we implement in our web applications.


What is Content Security Policy (CSP)?

CSP is a set of rules that restrict which resources (JavaScript, CSS, images, fonts, etc.) can be loaded on a web page. With this policy, you can prevent malicious code injection and significantly reduce the attack surface of your application.


How Does CSP Work?

CSP is defined through the HTTP header Content-Security-Policy. It specifies secure sources for scripts, stylesheets, images, and other resources.

Example of a CSP header:

Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com;
Enter fullscreen mode Exit fullscreen mode

In this case, we are defining:

  • default-src 'self': Allows only resources from the same domain to be loaded.
  • script-src 'self' https://apis.google.com: Only local scripts and those from Google can be executed.

Content Security Policy Options

CSP allows defining rules for different types of resources:

  • default-src: Defines the default source for all resource types unless specific directives are provided.
  • script-src: Controls where scripts can be loaded from.
  • connect-src: Defines the allowed endpoints for AJAX connections, WebSockets, and APIs like Fetch and XHR.
  • style-src: Restricts the allowed stylesheets.
  • font-src: Specifies where fonts can be loaded from.
  • frame-src: Controls which domains can be loaded within iframes.
  • img-src: Defines the allowed sources for images.
  • object-src: Specifies where objects like Flash and plugins can be loaded from.

A more complete CSP header example:

Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';
Enter fullscreen mode Exit fullscreen mode

Configuring CSP in Apache

If your web server is Apache, you can configure CSP by adding the following directive to the .htaccess or httpd.conf file:

<IfModule mod_headers.c>
    Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';"
</IfModule>
Enter fullscreen mode Exit fullscreen mode

This ensures that all requests are filtered according to the defined security rules.


Configuring CSP in Nginx

If you are using Nginx, you can enable CSP by adding the following directive to your server configuration:

server {
    listen 80;
    server_name example.com;

    add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';" always;
}
Enter fullscreen mode Exit fullscreen mode

This configuration ensures that all resources follow the specified security rules.


Securing Your Application with CSP and JavaScript

1. Blocking Inline Scripts

CSP can block inline scripts, preventing malicious code from being injected into HTML elements. To do this, we should avoid using:

<script>alert('XSS!');</script>
Enter fullscreen mode Exit fullscreen mode

And configure CSP to prevent inline scripts:

Content-Security-Policy: script-src 'self';
Enter fullscreen mode Exit fullscreen mode

If you need to execute inline scripts, you can use hashes or nonces to allow only specific scripts.

2. Using Nonces to Allow Specific Scripts

A nonce (unique number per request) allows only signed scripts to be executed:

Content-Security-Policy: script-src 'nonce-random123';
Enter fullscreen mode Exit fullscreen mode

In HTML:

<script nonce="random123">console.log('Allowed by CSP');</script>
Enter fullscreen mode Exit fullscreen mode

3. Preventing Untrusted Resource Loading

By restricting external sources, we ensure that only trusted resources are loaded. A secure CSP might be:

Content-Security-Policy: default-src 'self'; img-src 'self' https://images.example.com; font-src 'self' https://fonts.googleapis.com;
Enter fullscreen mode Exit fullscreen mode

Here, we are allowing only images and fonts from specific domains.


Monitoring and Testing CSP

To test if your application is protected, you can configure CSP in report-only mode:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report-endpoint;
Enter fullscreen mode Exit fullscreen mode

This allows monitoring violations without blocking resources.


Conclusion

Implementing Content Security Policy is one of the most crucial steps in ensuring the security of modern web applications. With a well-configured CSP, you significantly reduce the risk of XSS attacks and improve protection against malicious code injections.

If you haven’t implemented CSP on your website yet, now is the time to start!

To read more about: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Top comments (0)