Add a Content-Security-Policy on WordPress
Why it matters
Without a CSP the browser runs any script that ends up in your pages, so a single injection bug gives an attacker control of what visitors see and do. A policy limits where scripts, frames and plugins may load from.
Staged change. Do this in stages and check each one before the next, so a mistake does not break your site or your mail.
The fix
- Pick where to set it. A CDN or the web server (see their tabs) covers cached pages too; a maintained security-headers plugin from the WordPress.org directory with a report-only option is the no-code route; the must-use plugin below works for pages WordPress renders through PHP, not for static files or pages a cache serves without running PHP.
- Stage 1: send the report-only policy and browse the front end with the developer console open. WordPress core, themes and plugins print inline scripts, so expect reports for them.
- Stage 2: enforce. If inline scripts cannot be given nonces, the practical first enforced policy adds 'unsafe-inline' to script-src while keeping object-src, base-uri and frame-ancestors; replacing it with nonces is a later project, and nonces do not work with full-page caching.
wp-content/ mu-plugins/ csp.php
<?php /* * Plugin Name: Content-Security-Policy (report only) */ add_action( 'send_headers', function () { header( "Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'" ); } );
Related
- Reported by the Content-Security-Policy check
- Enforce the report-only Content-Security-Policy
- Send the Content-Security-Policy as an HTTP header
- Restrict where scripts can load from
- Replace 'unsafe-inline' scripts with nonces or hashes
- Remove 'unsafe-eval' from script-src
- Remove wildcard sources from script-src
- Set object-src to 'none'
- Add base-uri to the Content-Security-Policy
- Reduce reliance on inline styles
- Fix the Content-Security-Policy syntax
Scan your domain to see whether this applies to you.