Linux 软件免费装
Banner图

Codo Content Security Policy

开发者 cododigital
更新时间 2026年11月7日 23:57
PHP版本: 7.4 及以上
WordPress版本: 7.1
版权: GPLv2 or later
版权网址: 版权信息

标签

clickjacking xss csp content security policy security headers

下载

1.1.0 1.0.0

详情介绍:

A Content Security Policy tells browsers which scripts, styles, fonts, images, frames and form targets your pages may use. Anything else is blocked, which stops a whole class of attacks: scripts injected from other hosts, data sent to attackers' servers, forms hijacked to post elsewhere, and your site being framed for clickjacking. The hard part is building a policy without breaking the site. Codo Content Security Policy is designed around that. It is built by Codo Digital, a UK web development and managed hosting company, and is the policy plugin we use on our own clients' sites. Everything is free. There is no Pro version, no upsell, no account to create and no tracking. Safe by default Changing an enforced policy without breaking it Violation reports, built for slow sites Scanning Also Why 'unsafe-inline' is in the starting policy Almost every WordPress site prints inline scripts (core, themes and plugins all do). The strict alternatives don't fit most sites: nonces don't survive full-page caching, and hashes break whenever an inline script changes. So the starting policy keeps 'unsafe-inline' for scripts and styles and works as an allowlist. It still blocks scripts from hosts you haven't listed, eval, plugins, <base> hijacking, form hijacking, data exfiltration through connect-src, and clickjacking. If your site can do without inline scripts, remove 'unsafe-inline' from script-src. The change goes through a draft first, and the Reports tab shows exactly what breaks. For hosts and agencies: configuration in wp-config.php define( 'CODO_CSP_DISABLE', true ); // Send no policy headers at all. define( 'CODO_CSP_MODE', 'enforce' ); // Or 'report-only'. define( 'CODO_CSP_REPORT_URI', 'https://example.report-uri.com/r/d/csp/enforce' ); define( 'CODO_CSP_LOGIN', false ); // No policy on wp-login.php. Constants override the settings screen and show as read-only there. For developers Source, issues and tests: github.com/Codo-Digital-Ltd/codo-content-security-policy.

安装:

  1. Install from Plugins > Add New, or upload the codo-content-security-policy folder to /wp-content/plugins/.
  2. Activate the plugin. The policy starts in Report-Only and collects reports for 7 days.
  3. Go to Settings > Content Security Policy. Add presets for the services your site uses, and use the Scan tab to check your main pages.
  4. Browse the site, then check the Reports tab. Allow what you recognise.
  5. When reports stop appearing, click Enforce the policy.

升级注意事项:

1.1.0 Import rules found by a scan, with a safety review. New rules can no longer allow whole shared domains or public CDNs for scripts; existing rules keep working and are flagged. 1.0.0 First release.

常见问题:

How is this different from security plugins that include CSP?

It only does Content Security Policy. Security suites tend to offer CSP as one setting among many, often a text box for the header with little help building it. This plugin is built around getting the policy right: it starts in Report-Only, collects violation reports on your own site, scans your pages for the sources they use, and puts changes to an enforced policy through a draft first. It adds no firewall, login protection or malware scanning, so it sits alongside whichever security plugin you already use. Just make sure that plugin isn't also sending a policy header; the scan warns you if one is.

Will this break my site?

Not while it's in Report-Only, which is how it starts: browsers only report. Enforce it once the Reports tab is quiet. After that, changes that could block something go through a draft first.

Why aren't logged-in users excluded?

They're the users an attack on the front end usually targets, because their browser holds an admin session. So the front end gets the same policy for everyone. The only exceptions are page builders and the Customizer preview (see below). Note that the admin bar adds a few requests for logged-in users that visitors don't make, so expect a few reports that only logged-in users trigger.

My page builder or the Customizer stopped working

Front-end editors inject inline code that an enforced policy blocks, so no policy is sent inside them by default. This applies to the Customizer preview and to Elementor, Divi, Beaver Builder, Bricks, Oxygen, WPBakery, Thrive, Brizy and Avada, for users who can edit. Make sure "Page builders" is ticked on the Settings tab. For other builders, use the codo_csp_skip_request filter.

I changed the policy but visitors still get the old one

Full-page caches store the headers with the page. The plugin purges the common cache plugins when the policy changes. For anything else, such as Cloudflare, Varnish, NGINX fastcgi_cache without Nginx Helper, or your host's cache, purge it yourself or hook codo_csp_purge_caches.

Why does the scan say another policy header is being sent?

Browsers enforce every policy they receive, so a second one (from your server configuration, a CDN, a security plugin or your host) can block something this plugin allows. Remove the other one, or make sure it allows at least as much. A page cache still holding an older version of this plugin's header can also cause the warning; purge it and scan again.

My site returns 502 errors after adding many sources

NGINX's default FastCGI buffer is 4 KB or 8 KB, and a large policy can exceed it ("upstream sent too big header"). The policy screen shows the header size and warns over 4 KB. Remove sources you no longer need (wildcards like https://*.example.com can replace several hosts), or raise fastcgi_buffer_size and fastcgi_buffers.

Why can't I add 'https:' or * to script-src?

It would allow scripts from any host, which defeats the policy. Add the specific hosts instead. The same applies to https://*, data: and blob:, and to default-src (which covers scripts when script-src is absent), object-src, worker-src and base-uri. Workers may use blob:, because WordPress's emoji loader needs it.

Why can't I add a nonce?

Nonces must change on every response, so they can't be a fixed source. They also don't survive full-page caching. Use a hash for a specific inline script, keeping in mind that browsers ignore 'unsafe-inline' once a hash is present.

A report says something was blocked on a page I don't recognise

Anyone can send reports to your site, and browser extensions inject content that violates every policy (the plugin drops reports it can identify as extensions). Only allow sources you recognise. Sources a scan also found are marked.

Do reports slow the site down?

Very little. They are handled before the theme loads and init runs, and processing is rate-limited (120 requests a minute by default). Identical reports update a counter instead of adding rows. Collection also switches itself off at the end of the period you choose.

How long are reports kept?

Reports not seen for 30 days are deleted by a daily WP-Cron task, and you can clear them at any time. Reports store the directive, the blocked origin (not the full URL) and the latest page it happened on (the path, not the query string). No IP addresses or user agents are stored.

Does the plugin send data to Codo Digital?

No.

Is it multisite compatible?

Yes. Each site has its own policy, mode and reports, managed by its administrators. Network administrators can add network defaults (Network Admin > Settings > Content Security Policy). These are merged into every site's policy and can't be removed by site administrators. A network default that creates a directive on a site keeps the sources that site inherited for it, so adding one never blocks a site's own resources. 'none', hashes and 'strict-dynamic' can't be network defaults. Removing a network default applies to every site straight away, without a draft.

更新日志:

1.1.0 1.0.0