Skip to main content

Configuring Content Security Policy (CSP) Directives at Seravo

Protect your WordPress site against XSS and clickjacking attacks. Learn how to configure CSP directives, use report-only mode, and test settings at Seravo.

Content Security Policy (CSP) is an HTTP response header that defines which content sources (such as scripts, stylesheets, images, and fonts) a browser is permitted to load. A properly configured CSP acts as a robust defense layer, preventing unauthorized code execution in the browser and shielding your site from Cross-Site Scripting (XSS) and clickjacking attacks (unauthorized embedding of your site inside an invisible frame).

At Seravo, all nginx servers include a baseline CSP configuration by default in /data/wordpress/nginx/security.conf:

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

This default rule instructs the browser to automatically load any insecure (HTTP) assets over an encrypted HTTPS connection. This guide explains how you can safely introduce a broader, stricter CSP policy without breaking your site’s layout or dynamic features.

Prerequisites

  • SSH access to the server.

  • An understanding of the external resources used by your site (such as Google Analytics, embedded videos, live chat widgets, or external web fonts).

Key Directives and WordPress Considerations

Before deploying rules, it is helpful to familiarize yourself with common CSP directives:

  • default-src: Fallback rule for resource types that do not have their own explicit directive.

  • script-src: Permitted JavaScript sources.

  • style-src: Permitted CSS stylesheets and styling sources.

  • img-src: Permitted image sources.

  • font-src: Permitted font sources (e.g., Google Fonts).

  • frame-ancestors: Defines which domains are allowed to embed this site in an <iframe> (protects against clickjacking).

Important Note for WordPress Sites:

The WordPress core, numerous plugins, and popular page builders (such as Elementor and Divi) rely heavily on dynamically generated inline scripts and styles (inline styles / scripts). Because of this, WordPress environments almost always require the 'unsafe-inline' keyword in both script-src and style-src, and frequently 'unsafe-eval' for dynamic script evaluation. Omitting these will likely break your site's dashboard or visual layout.

Step-by-Step Safe Implementation of CSP

Because overly strict CSP policies block browsers from loading required assets, implementation should always follow a staged approach using report-only mode.

1. Configure Rules in Report-Only Mode

Start with the Content-Security-Policy-Report-Only header. In this mode, the browser does not block any assets; it only logs potential violations to the developer console.

  1. Connect to your site via SSH and open your nginx security configuration file:

    nano /data/wordpress/nginx/security.conf
  2. Replace or update the existing CSP directive with your test policy. Here is a solid starting baseline:

    add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src 'self' data: https:; frame-ancestors 'self';";
  3. Save the file (in nano: Ctrl + O, Enter, and exit with Ctrl + X).

2. Test nginx Syntax and Restart

Before restarting nginx, always confirm that there are no syntax errors in the configuration files:

wp-restart-nginx --test

If the output confirms that syntax is ok, restart nginx:

wp-restart-nginx

3. Monitor and Resolve Violations in Browser Developer Tools

  1. Open your website in a browser and open the developer tools (press F12 and select the Console tab).

  2. Navigate across various page types (front page, contact forms, checkout/cart pages, and the WP-admin dashboard).

  3. Look for yellow or red CSP violation warnings (e.g., "Refused to load the script...").

  4. If a legitimate external service needed by your site (such as a YouTube embed or chat script) triggers a warning, add that service’s domain to the appropriate directive in security.conf and restart nginx.

4. Activate Protection in Production

Once you have tested the site thoroughly and no unintended warnings appear in the console, you can enforce the policy:

  1. Open the file again:

    nano /data/wordpress/nginx/security.conf
  2. Change the header directive name from Content-Security-Policy-Report-Only to Content-Security-Policy.

  3. Save the file and restart nginx:

    wp-restart-nginx

Testing and Troubleshooting

  • How do I verify active headers from the command line?

    You can inspect the headers returned by your web server using:

    curl -I https://example.com

    Check the output to ensure the content-security-policy header appears with your specified rules.

  • Did your site layout or features break immediately after enforcement?

    This usually indicates that a theme asset requires 'unsafe-inline' or an external domain is missing from the whitelist. You can quickly roll back by changing the header name back to Content-Security-Policy-Report-Only and running wp-restart-nginx, restoring normal site functionality while you adjust your directives.

See Also

Content Security Policy is a powerful security mechanism, but keeping it effective requires ongoing maintenance, especially when installing new plugins or third-party tracking scripts. By taking advantage of report-only mode, you ensure your site stays protected without risking unintended downtime. If you need assistance formulating complex CSP rules, Seravo’s WordPress specialists are always ready to help at [email protected].

Did this answer your question?