When to use this guide
Content-Security-Policyheader not implemented- CSP score is -25 or lower
How urgent is this? CSP is medium priority but technically complex. A missing CSP leaves the site vulnerable to cross-site scripting (XSS) attacks โ where an attacker injects malicious scripts into your pages. However, a misconfigured CSP can break the site entirely (blocking legitimate scripts, payment widgets, fonts, or analytics). Do not rush this. Take time to test thoroughly in
report-only mode before enforcing.This guide requires developer access. Implementing CSP correctly requires inspecting which scripts, stylesheets, fonts, and other resources the site loads, and where they come from. On WordPress this typically means access to the theme or a code-level plugin. This is not a one-click fix.
Who does this?
The developer responsible for the WordPress theme or codebase. Basic WordPress admin access is not sufficient โ this requires someone comfortable reading browser console output and editing code or advanced plugin settings.
Background: what does CSP do?
| Concept | What it does |
|---|---|
| Content-Security-Policy | Tells the browser which sources are allowed to load scripts, styles, images, and other resources |
| XSS protection | Prevents attackers from injecting and executing malicious scripts on your pages |
| report-only mode | Logs violations without blocking anything โ safe to use while building the policy |
| enforce mode | Actively blocks disallowed resources โ only use after thorough testing |
Step 1: Audit what your site loads
Before writing a CSP, you need to know what resources your site loads and from where. Open the site in Chrome or Firefox, open DevTools (F12) โ Network tab, reload the page, and note:
- All script sources (
<script>tags and JS files) - All stylesheet sources (
<link>tags and CSS files) - All font sources (Google Fonts, Adobe Fonts, etc.)
- All iframe sources (YouTube embeds, payment widgets, etc.)
- All image sources
Pay special attention to third-party sources (Google Analytics, Facebook Pixel, payment providers, CDNs).
Step 2: Start with report-only mode
Add the following HTTP header via your WordPress security plugin (e.g. HTTP Headers by Fer Perez):
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
This logs all violations to the browser console without blocking anything. Leave it running for a few days and collect violations โ they will tell you exactly which sources need to be whitelisted.
Step 3: Build the policy
Based on the violations collected in Step 2, build a policy that allows all legitimate sources. A typical WordPress site using Google Fonts and Analytics might look like:
Content-Security-Policy:default-src 'self';script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com;style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;font-src 'self' https://fonts.gstatic.com;img-src 'self' data: https:;frame-src 'self' https://www.youtube.com;
Avoid
unsafe-inline and unsafe-eval where possible โ they significantly weaken the policy. Some WordPress themes and plugins require them, but try to minimise their use.Step 4: Switch to enforce mode
Once the policy in report-only mode produces no unexpected violations:
- Replace
Content-Security-Policy-Report-OnlywithContent-Security-Policy - Test all key pages: homepage, donation flow, contact form, any embedded widgets
- Check the browser console for any new violations and fix them
Step 5: Verification
- Re-run securityheaders.com โ CSP should now show green
- Re-run Mozilla HTTP Observatory โ score should improve significantly
- Check the browser console on key pages for any remaining CSP violations