Content Security Policy WordPress: How to Add CSP Safely

by

content security policy wordpress feature image

Content-Security-Policy is an effective way to strengthen your WordPress site’s defenses, but it works best when it’s tailored to how your site loads content.

For a reliable content security policy WordPress setup, you need a policy that accounts for your scripts, styles, images, and third-party resources.

As part of a layered WordPress security strategy, CSP can help reduce risk without getting in the way of normal site functionality.

TL;DR: A Content-Security-Policy header tells browsers which scripts, styles, images, fonts, forms, and frames your WordPress site can load. Start with Content-Security-Policy-Report-Only, keep a fresh backup ready, test your real pages and admin area, then switch to the enforced Content-Security-Policy header once nothing important is being blocked.

The hard part isn’t adding the header. The hard part is making sure your contact form, checkout, analytics, embeds, page builder, and block editor still work after you add it.

What a CSP header does

A Content Security Policy is a browser rule sent by your server. The browser reads it before loading the page and uses it to decide what is allowed. For example, your CSP can say:

  • load scripts only from your domain and trusted services
  • allow images from your site, CDN, and secure image sources
  • let forms submit only to approved places
  • stop other sites from framing your pages
  • block old plugin-style objects that modern WordPress sites rarely need

CSP is useful because it can reduce the damage from cross-site scripting, often called XSS, where injected JavaScript runs in a visitor’s browser. A good policy can stop unknown scripts from loading, limit where data can be sent, and block risky page behavior. That matters on WordPress because scripts can come from more than the theme. Plugins, embeds, payment tools, and admin screens all add their own moving parts.

It doesn’t make WordPress hack-proof. It doesn’t remove malware, fix vulnerable plugins, or replace a firewall. Think of it as one browser-side safety layer.

CSP is one of several HTTP security headers that help harden a WordPress site. Others, including X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and Strict-Transport-Security (HSTS), protect different aspects of browser behavior. Together, they provide stronger browser-side defenses than any single header on its own

🔎 Note: WordPress doesn’t know which services your site needs. A blank site may need very little. A store that uses payments, spam checks, analytics, embeds, and a page builder needs more. That’s why copying someone else’s CSP is risky.

Check your current headers

Before changing anything, see what your site already sends. Use a header scanner such as SecurityHeaders.com, or run this from a terminal:

curl -I https://example.com

Look for either header:

Content-Security-Policy:
Content-Security-Policy-Report-Only:

If you don’t see either one, CSP is probably not active for that URL. Check more than the homepage if your site has checkout, account pages, or important landing pages.

Curl output showing a live Content-Security-Policy header check

If you do see a CSP header, don’t add another one until you know where the first one comes from. It may be set by a plugin, host panel, server config, or CDN. Two policies can apply at the same time. When that happens, the browser may block more than the policy you are looking at.

This is one of the few places where “more security headers” can make the site harder to run, because the browser applies what it receives without caring which tool added it.

Start with report-only mode

Report-only mode is the safest way to configure CSP on WordPress. Instead of blocking resources right away, Content-Security-Policy-Report-Only tells the browser what would be blocked. Your site keeps working while you collect warnings.

Plugin FAQ explaining Content-Security-Policy report-only mode

Here is the rollout I would use:

  • Create a restore point before editing headers: Keep a backup ready, especially if you plan to edit server files.
  • Choose one place to manage CSP: Use a plugin, host panel, CDN, Apache, or nginx. Avoid setting the same policy in several places.
  • Add a report-only policy first: Use Content-Security-Policy-Report-Only, not the enforced header.
  • Test the pages people actually use: Visit a blog post, a form, checkout or login pages, embeds, and the WordPress editor.
  • Read browser console warnings: Open DevTools and look for CSP violations that say which directive and source caused the issue.
  • Allow only sources you trust: If a warning points to a service you use, add it narrowly. If it points to an old script you forgot about, remove the script instead.
  • Switch to enforcement after testing: Change the header to Content-Security-Policy only when the important flows are clean.
  • Retest after major site changes: New plugins, tracking scripts, payment tools, and page builders can all need policy updates.

⚠️ Note: A scanner grade is not proof that your CSP works. It can confirm the header exists, but it cannot tell you whether your checkout, editor, or contact form still works.

Know the directives you will edit

CSP has many directives, but most WordPress sites deal with a smaller set.

DirectiveWhat it controls
default-srcThe fallback rule when a more specific rule is not set
script-srcJavaScript files and inline scripts
style-srcCSS files and inline styles
img-srcImages, avatars, tracking pixels, and some CDN media
font-srcWeb fonts
connect-srcBrowser requests made by JavaScript, including REST API calls and analytics beacons
frame-srcEmbedded videos, maps, payment frames, and similar content
frame-ancestorsWhich sites can place your pages inside a frame
form-actionWhere forms are allowed to submit
base-uriWhich base URLs the page can use
object-srcOld embedded objects, which most sites can block
upgrade-insecure-requestsAsks the browser to load HTTP resources over HTTPS where possible

For many WordPress sites, object-src ‘none’ and base-uri ‘self’ are good hardening defaults. They remove risk without usually affecting normal pages.

Be more careful with script-src and style-src. Themes, plugins, analytics tools, and page builders often rely on JavaScript or inline styles. This is where most breakage happens.

🛠️ Note: Values like ‘unsafe-inline’ and ‘unsafe-eval’ weaken CSP. Some WordPress sites need them for a while, but they should be treated as compromises. If your developer can replace inline code with files, nonces, or hashes, which are per-script approvals the browser can verify, the policy gets stronger.

Use a starter policy carefully

There isn’t a universal WordPress CSP. A small blog and a WooCommerce store shouldn’t have the same policy. For a small site, this can be a reasonable report-only starting point:

Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; img-src 'self' data: https:; font-src 'self' data: https:; script-src 'self'; style-src 'self'; connect-src 'self'; frame-src 'self';

Don’t treat that as the final answer. Treat it as the first test.

If your site uses embeds or custom fonts, you’ll see violations. Payment scripts, spam checks, and analytics may show up too. Add the sources you recognize and need. Keep the policy tight where you can.

For example, allowing img-src https: may be practical for a media-heavy site. Allowing script-src https: is much broader because it allows JavaScript from any secure domain. That is a bigger tradeoff.

Add CSP with a plugin

A WordPress header plugin or host security tool is often the easiest route if you don’t want to edit server files. Look for a tool that gives you:

  • report-only mode
  • separate controls for major directives
  • readable policy output
  • quick disable or rollback
  • current WordPress compatibility
  • clear cache behavior

Then follow this workflow:

WordPress security headers plugin settings overview
  • Install a header management plugin or use your host’s tool: Choose one that lets you edit the actual CSP value.
  • Enter the policy in report-only mode: Avoid a one-click enforce option until you have tested.
  • Save and clear every cache layer: Clear the cache in WordPress, then clear host or CDN cache if those sit in front of the site. If old headers keep appearing, check for WordPress caching issues before changing the policy again.
  • Confirm the header is present: Use a header scanner or curl -I to check the live response.
  • Test frontend and admin screens: Include the block editor, forms, embeds, and payment pages if relevant.
  • Adjust the policy from real warnings: Add trusted sources only when a feature needs them.
  • Enforce after the warnings are handled: Switch from report-only to the live CSP header and test again.

The useful plugin screens are the ones that expose the actual policy, not just an enable switch.

CSP plugin controls for policy and report URI fields

I would skip any plugin that only says “enable CSP” without showing the policy. You need to know what the browser is being told.

Add CSP in .htaccess on Apache

If your host uses Apache, you may be able to add CSP in the site’s .htaccess file. This file usually sits in the same folder as wp-config.php.

Backup the site first. At minimum, save a clean copy of .htaccess somewhere you can restore fast. One bad character in this file can cause a server error.

Backup details

For report-only testing, add this outside the WordPress rewrite block unless your host says otherwise:

<IfModule mod_headers.c>
  Header set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; img-src 'self' data: https:; font-src 'self' data: https:; script-src 'self'; style-src 'self'; connect-src 'self'; frame-src 'self';"
</IfModule>

After testing, enforce the same policy by changing the header name:

<IfModule mod_headers.c>
  Header set Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; img-src 'self' data: https:; font-src 'self' data: https:; script-src 'self'; style-src 'self'; connect-src 'self'; frame-src 'self';"
</IfModule>

If the header does not appear, your host may not allow mod_headers in .htaccess, or a cache may still be serving old responses.

Add CSP on nginx

nginx does not use .htaccess. CSP is usually added in the server configuration or through your host’s control panel.

Use report-only first:

add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; img-src 'self' data: https:; font-src 'self' data: https:; script-src 'self'; style-src 'self'; connect-src 'self'; frame-src 'self';" always;

After testing, enforce it:

add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; img-src 'self' data: https:; font-src 'self' data: https:; script-src 'self'; style-src 'self'; connect-src 'self'; frame-src 'self';" always;

Test the config before reloading nginx:

sudo nginx -t
sudo systemctl reload nginx

If you are on managed hosting and do not have server access, don’t guess. Use the host’s header settings or ask support where CSP should be added.

Common Content Security Policy WordPress issues

Most CSP problems are easy to find once you know where to look. Open DevTools, reload the page, and check the Console. In report-only mode, the warning tells you what would have broken. In enforced mode, it tells you what just broke.

Either way, the useful part is the directive name and the blocked source.

WordPress frontend demo page used while testing CSP headers
  • Fix missing layouts by checking style and font rules: Broken spacing, missing fonts, or unstyled pages usually point to style-src or font-src.
  • Fix dead buttons by checking script rules: If menus, sliders, checkout buttons, or page builder controls stop responding, look at script-src.
  • Fix broken forms by checking submit and connection rules: Form issues often involve form-action or connect-src.
  • Fix missing embeds by checking frame rules: Videos, maps, and payment widgets usually need frame-src.
  • Fix vanished images by checking image rules: Missing logos, avatars, CDN images, and tracking pixels usually involve img-src.
  • Fix HTTPS warnings at the source: upgrade-insecure-requests can help, but old http:// URLs should be updated in content, templates, or plugin settings.
  • Fix admin issues separately: A frontend policy can still break wp-admin. Test the editor, media library, and plugin screens before you enforce.
WordPress block editor screen to test before enforcing CSP

🧩 Note: Don’t whitelist every blocked domain just to make warnings disappear. If you don’t recognize a source, find what added it. CSP work often reveals old tracking tags and plugin leftovers that should be removed, not approved.

What CSP will not protect

CSP controls what the browser can load. It doesn’t scan your WordPress files or clean malware. It won’t patch vulnerable plugins, stop every login attack, or replace backups. That is why CSP belongs with the rest of your security stack:

This is where MalCare fits naturally. Use CSP as the browser-side layer, and use MalCare for broader WordPress security: firewall protection, malware detection and removal, and bot protection. If you already suspect a site is infected, scan and clean it before spending hours tuning headers. A clean site with a measured CSP is a much better target than a compromised site with a polished scanner grade.

FAQs

Should every WordPress site use a Content Security Policy?

Most WordPress sites benefit from CSP, but it should be tested before enforcement. A simple blog can use a tighter policy than a store or membership site with payment tools, embeds, forms, and analytics.

What is the safest way to add CSP to WordPress?

Start with Content-Security-Policy-Report-Only. It shows what would be blocked without breaking the site. After you fix the warnings on important pages, switch to Content-Security-Policy.

Can I add CSP without editing code?

Yes. A WordPress header plugin, host security panel, or CDN rule can add CSP without editing theme or server files. Use a tool that shows the full policy and supports report-only mode.

Why did CSP break my WordPress site?

CSP breaks a site when the policy blocks something the site needs. Scripts and inline styles are common causes. Forms, embeds, and old HTTP resources can trigger it too. Check the browser console before changing the policy.

Is CSP enough for WordPress security?

No. CSP helps reduce browser-side risk, especially around injected scripts, but it’s only one layer. You still need updates, clean plugins, backups, and malware scanning. Firewall protection and user access matter too.

Conclusion

A good WordPress CSP is built from your site, not borrowed from someone else’s. Start in report-only mode, test the public pages and admin screens that matter, then enforce the policy when the warnings make sense and the important features still work.

Keep the policy maintained after plugin or theme changes. Review it again when you add analytics, CDN rules, or checkout tools. CSP can make your site safer, but it works best beside the basics: updates, backups, security monitoring, malware scanning, and a firewall that protects the parts a browser header can’t see.

Category:

You may also like


How can we help you?

If you’re worried that your website has been hacked, MalCare can help you quickly fix the issue and secure your site to prevent future hacks.

My site is hacked – Help me clean it

Clean your site with MalCare’s AntiVirus solution within minutes. It will remove all malware from your complete site. Guaranteed.

Secure my WordPress Site from hackers

MalCare’s 7-Layer Security Offers Complete Protection for Your Website. 300,000+ Websites Trust MalCare for Total Defence from Attacks.