Skip to main content

Content Security Policy (CSP)

In this guide we explain how CSP works and how you can use it to improve your site’s security.

A Content Security Policy (CSP) is an HTTP response header that defines which resources (such as scripts, stylesheets, and images) a browser is allowed to load. CSP prevents unauthorized code execution in the user's browser, protecting your site against Cross-Site Scripting (XSS) and Clickjacking attacks.

Preventable Security Risks

  • Cross-Site Scripting (XSS): An attacker attempts to execute malicious JavaScript in the user's browser. CSP blocks scripts loaded from unauthorized or unknown sources.

  • Clickjacking: An attacker embeds your site inside an invisible frame (iframe) to trick users into clicking links or buttons. CSP restricts embedding your site on external web pages.

Default Settings at Seravo

Seravo's nginx environment includes a basic CSP directive enabled by default in /data/wordpress/nginx/security.conf:

add_header Content-Security-Policy "upgrade-insecure-requests";

This rule instructs the browser to automatically upgrade all insecure (HTTP) resource requests to secure (HTTPS) connections.

How to Safely Implement CSP

Overly restrictive CSP rules can break your website's layout or functionality. Implementation should always be done in phases:

  1. Test rules in report-only mode

    Configure your policy in test mode using Content-Security-Policy-Report-Only. In this mode, the browser does not block resources; instead, it logs any policy violations to the browser developer tools console (F12).

    Add the following rules to /data/wordpress/nginx/security.conf:

    add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;";

  2. Monitor and fix errors

    Browse your website and check the browser developer console (Console tab) to ensure no legitimate resources are triggering CSP warnings.

  3. Activate full CSP protection

    Once you confirm the rules work as intended, change the header name to Content-Security-Policy:

    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;";

Remember to restart nginx using the command wp-restart-nginx after making changes. You can test your configuration beforehand using wp-restart-nginx --test.

Common CSP Directives

  • default-src: Serves as a fallback for resource types that do not have an explicit directive defined.

  • script-src: Defines allowed sources for JavaScript.

  • style-src: Defines allowed sources for CSS stylesheets.

  • img-src: Defines allowed sources for images.

  • frame-ancestors: Prevents your site from being embedded on external websites (protects against Clickjacking).

WordPress Considerations

WordPress core, many plugins, and page builders (such as Elementor) rely heavily on inline scripts and styles.

  • In a WordPress environment, you will often need to include 'unsafe-inline' in the script-src and style-src directives.

  • If your site uses dynamically generated scripts, 'unsafe-eval' may also be required.

Testing Your Settings

You can inspect the active HTTP response headers sent by the server using, for example, the following command:

curl -I https://example.com

Check the output for the content-security-policy line to verify that nginx is serving your desired rules.

More Information About CSP

You can read more about CSP and its implementation for example in Mozilla's developer resources.

Did this answer your question?