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:
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:;";
Monitor and fix errors
Browse your website and check the browser developer console (Console tab) to ensure no legitimate resources are triggering CSP warnings.
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 thescript-srcandstyle-srcdirectives.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.
