WordPress Security

Content Security Policy for WordPress: Complete Implementation

Implement Content Security Policy (CSP) headers in WordPress to prevent XSS attacks and control resource loading.

S
Sarah Chen
8 min read
1,481 views
WordPress Content Security Policy implementation guide

Content Security Policy is a powerful defense against XSS and data injection attacks. CSP tells browsers which sources are allowed to load content, blocking malicious scripts.

Understanding CSP

What CSP Controls

  • Script sources (JavaScript)
  • Style sources (CSS)
  • Image sources
  • Font sources
  • Frame sources (iframes)
  • Connect sources (AJAX, WebSocket)
  • Form actions

How CSP Prevents XSS

Even if an attacker injects malicious script tags, CSP blocks execution because the source is not whitelisted.

Basic CSP Implementation

Minimal CSP Header

add_action('send_headers', 'wpfs_add_csp_header');
function wpfs_add_csp_header() {
    $csp = "default-src 'self'; ";
    $csp .= "script-src 'self'; ";
    $csp .= "style-src 'self' 'unsafe-inline'; ";
    $csp .= "img-src 'self' data:; ";
    $csp .= "font-src 'self'; ";
    $csp .= "frame-ancestors 'self';";

    header("Content-Security-Policy: " . $csp);
}

CSP Directives Explained

  • default-src - Fallback for unspecified directives
  • script-src - Allowed JavaScript sources
  • style-src - Allowed CSS sources
  • img-src - Allowed image sources
  • connect-src - Allowed AJAX/WebSocket targets
  • frame-src - Allowed iframe sources
  • frame-ancestors - Who can frame this page

WordPress-Specific CSP

Handling WordPress Requirements

function wpfs_wordpress_csp() {
    $nonce = wp_create_nonce('csp-nonce');

    $csp = array(
        "default-src 'self'",
        "script-src 'self' 'nonce-{$nonce}' 'strict-dynamic'",
        "style-src 'self' 'unsafe-inline'",
        "img-src 'self' data: https:",
        "font-src 'self' data:",
        "connect-src 'self'",
        "frame-src 'self' https://www.youtube.com https://player.vimeo.com",
        "frame-ancestors 'self'",
        "base-uri 'self'",
        "form-action 'self'"
    );

    return implode('; ', $csp);
}

Inline Script Nonces

// Add nonce to inline scripts
add_filter('script_loader_tag', 'wpfs_add_script_nonce', 10, 3);
function wpfs_add_script_nonce($tag, $handle, $src) {
    if (!$src) {
        $nonce = wp_create_nonce('csp-nonce');
        return str_replace('