Content-Security-Policy Headers in WordPress: XSS Defense with Nonces

A Content-Security-Policy header is the single most effective defense against XSS attacks — it tells the browser which scripts, styles, and resources are allowed to execute. Implementing CSP on WordPress requires careful allowlisting because core and plugins rely on inline scripts.

Problem: A WordPress site is missing Content Security Policy headers — or has a permissive default-src 'unsafe-inline' policy — leaving it exposed to cross-site scripting attacks through injected inline scripts.

Solution: Add a Content-Security-Policy header via Nginx or Apache configuration. Start with a Report-Only policy to detect violations without blocking anything, use a nonce-based approach for inline scripts with the wp_script_attributes filter, and tighten the policy incrementally based on violation reports.

The examples below add a CSP header via PHP with a nonce for inline scripts, collect Gutenberg-specific allowlists, and show how to run CSP in report-only mode first to catch violations without breaking the site.

Start with Report-Only mode to discover violations before enforcing:

NOTE: Gutenberg's block editor requires 'unsafe-eval' in the admin CSP because it uses eval() internally — so a strict CSP is most practical on the front end only. Use the is_admin() check to apply different policies to front and back end.

Leave Comment

Your email address will not be published. Required fields are marked *