Skip to content

How to implement Content Security Policy in WP Engine

Is your WordPress site truly secure, or are you leaving the door wide open for hackers? Discover the one security feature most WP Engine users completely ignore.


Content Security Policy (CSP) is a powerful security feature that most WordPress site owners overlook. Learn how to implement CSP using WP Engine's Web Rules to protect your site from malicious scripts and cross-site scripting attacks.

csp
TL;DR
  • Implementing a Content Security Policy (CSP) adds a crucial security layer to WordPress sites, preventing cross-site scripting and malicious code injection.
  • CSP acts like a security guard for your site, specifying which files and scripts browsers can safely load, thereby blocking harmful scripts.
  • WP Engine's Web Rules settings offer a straightforward way to configure CSP, with varying levels of security from quick implementations to advanced nonce-based setups.
  • Testing and careful planning are essential, starting with policies in a staging environment and refining rules to balance security and functionality.

Your WordPress site’s security setup might be incomplete, even with quality hosting. While WP Engine provides solid platform protection, the majority of websites remain vulnerable to cross-site scripting attacks that can slip through standard defenses.

The often-overlooked solution? Content security policy configuration.

Most site owners never explore WP Engine’s Web Rules settings, missing an opportunity to add an important security layer. Without proper CSP headers, malicious scripts can potentially execute and compromise your visitors’ data.

Implementing content security policy creates an additional defense that helps block these attacks before they impact your site.

Ready to strengthen your security setup? We’re going to delve deep into details about the whole process of implementing CSP header.

Understanding Content Security Policy fundamentals

Content Security Policy is like a security guard for your website. It tells your visitor’s browser which files and scripts are safe to load.

Key security benefits

CSP blocks harmful scripts from running on your site. Furthermore, it prevents hackers from stealing visitor data and stops malicious code injection. And as a bonus, it can make your site load faster by blocking unwanted content. Learn more about the benefits of a faster website.

Core directives

Each directive controls a specific type of content:

  • default-src: Sets basic rules for all content types (JavaScript, images, CSS, fonts)
  • script-src: Controls which JavaScript files can run
  • style-src: Manages CSS stylesheets and design files
  • img-src: Decides which images can load
  • font-src: Controls web font sources
  • connect-src: Manages data connections and API calls
  • frame-src: Controls embedded content like videos
  • object-src: Handles plugins and embedded objects

Each directive works as a filter that checks content before allowing it to load.

Step-by-step CSP implementation in WP Engine

Step 1: Planning your CSP strategy

Before adding any rules, check what your site uses. Look for plugins that load external scripts, themes with custom fonts, and any third-party tools like analytics or chat widgets. Make a list of all outside resources your site needs to work properly.

Step 2: Testing and validation

Before implementing CSP, set up your testing tools:

Browser developer tools

Open your browser’s developer tools and check the Console tab. When CSP blocks something, you’ll see violation messages that explain what was blocked and why. These messages help you understand what needs fixing.

You can also measure rendering time using Chrome dev tools to ensure CSP implementation doesn’t negatively impact performance.

CSP testing tools 

Use these free online tools to check your CSP:

Screaming Frog SEO Spider testing 

Use Screaming Frog’s SEO Spider to crawl your site and check for CSP-related issues. This helps catch problems across your entire site that you might miss during manual testing.

You’ll be able to find details about which page is missing the security header under the Issues tab on the right sidebar, and if you select any of the issues detected, the specific pages for that issue will appear on the left side.

screaming frog ui

Report-only mode 

Start with Content-Security-Policy-Report-Only instead of Content-Security-Policy. This mode reports violations without blocking content, letting you test safely before going live.

wpengine adding header rule

WP Engine testing tips 

Always test CSP changes on your staging site first. Check Web Rules order carefully since rules at the top take priority. You should also monitor your site’s loading speed after adding CSP rules.

Here is also a checklist of what you should check:

  • Check console errors in browser developer tools for CSP violations
  • Test visual elements like image galleries, sliders, and video embeds
  • Verify functional features work properly:
    • Contact forms and newsletter signups
    • Pop-ups and modal windows
    • Shopping cart and checkout processes
    • Login and registration forms
  • Test third-party integrations (analytics, chat widgets, social media feeds)

Step 3: Choose your implementation level

Select the approach that best fits your technical comfort level and security requirements. Each level offers different trade-offs between security, flexibility, and ease of implementation:

Level 1 (Quick Implementation) provides basic protection with minimal effort but uses permissive settings like ‘unsafe-inline’ and ‘unsafe-eval’ that significantly reduce security benefits. While this approach prevents your site from breaking, it leaves you vulnerable to many of the attacks CSP is designed to prevent.

Level 2 (Manual Configuration) offers much better security by explicitly defining allowed sources, but creates a rigid policy that can break when you add new plugins, themes, or third-party services. Every time you update your site’s functionality, you’ll need to manually update your CSP policy to accommodate new resources.

Level 3 (Nonce-Based Implementation) provides the most robust security while maintaining flexibility. By using dynamically generated nonces, you can allow legitimate inline scripts while blocking malicious ones. This approach requires more technical setup but offers the best balance of security and functionality for WordPress sites.

Level 1: Quick implementation (Beginner) 

This is the fastest way to add CSP protection without breaking your site. In your WP Engine dashboard, go to Web Rules and click the Header rules tab. Click “Add header rule” and set up:

  • Action: Set
  • Name: Content-Security-Policy
  • Value: default-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’; img-src ‘self’ data:; font-src ‘self’ data:; connect-src ‘self’;
content security policy header in wp engine

This policy allows most WordPress functionality while providing basic protection. The ‘unsafe-inline’ and ‘unsafe-eval’ settings reduce security but prevent most site breakage.

Level 2: Manual configuration (Intermediate)

For better security, manually identify and whitelist your site’s resources.

  1. Start with a restrictive policy: default-src ‘self’;
  2. Test your site and check console errors
  3. Add specific domains for each broken resource
  4. Gradually build a comprehensive policy like:
default-src 'none'; 
script-src 'self' https://www.googletagmanager.com https://js.hs-scripts.com; 
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; 
img-src 'self' data: https://secure.gravatar.com; 
font-src 'self' https://fonts.gstatic.com; 
connect-src 'self' https://api.hubapi.com; 
frame-src 'self' https://www.youtube.com; 
object-src 'none';

You can also use the CSP Generator extension (csper.io) to help analyze your site and automatically generate appropriate CSP policies based on the resources it detects. However you need to keep in mind that you’ll need to visit and analyze different pages so it will create a CSP header for the whole site. If anything on the site breaks after adding the CSP header, you should check errors displayed in the Console tab of your browsers developer tools and add the missing values to the header to account for the resources that were denied, which caused the breakage on your site.

Level 3: Nonce-based implementation (Advanced) 

The most secure approach uses nonces to allow specific inline scripts. Add this code to your theme’s functions.php and edit the CSP header value like you would in the 2. Level with manual configuration we described above while leaving the dynamic nonce value definition as it is:

function generate_csp_nonce() {
    static $nonce = null;
    if ($nonce === null) {
        $nonce = wp_create_nonce('script_nonce_' . time());
    }
    return $nonce;
}

// Send CSP header early in the request
add_action('send_headers', function() {
    if (!is_admin()) {
        $nonce = generate_csp_nonce(); 
        header("Content-Security-Policy: default-src 'self' example.com *.example.com; style-src 'self' example.com *.example.com 'unsafe-inline' fonts.googleapis.com; script-src 'self' example.com *.example.com 'nonce-{$nonce}' www.googletagmanager.com {$unsafe_eval}; img-src 'self' example.com *.example.com data:; font-src 'self' example.com *.example.com fonts.gstatic.com; connect-src 'self' example.com *.example.com; frame-src 'self' example.com *.example.com; object-src 'none';");
    }
});

// Start output buffering to add nonces to scripts
add_action('init', function() {
    if (!is_admin()) {
        ob_start(function($html) {
            $nonce = generate_csp_nonce();
            $html = preg_replace_callback(
                '/<script\b(?![^>]*\bnonce\s*=)([^>]*)>/i',
                function($matches) use ($nonce) {
                    return '<script nonce="' . esc_attr($nonce) . '"' . $matches[1] . '>';
                },
                $html
            );
            return $html;
        });
    }
}, 1);

// Add nonce to enqueued scripts
add_filter('script_loader_tag', function($tag, $handle, $src) {
    $nonce = generate_csp_nonce();
    if (strpos($tag, 'nonce=') === false) {
        $tag = str_replace('<script', '<script nonce="' . esc_attr($nonce) . '"', $tag);
    }
    return $tag;
}, 10, 3);

// Handle inline scripts
add_filter('wp_inline_script_attributes', function($attributes) {
    $nonce = generate_csp_nonce();
    $attributes['nonce'] = $nonce;
    return $attributes;
});

// Process output buffer
add_action('shutdown', function() {
    while (ob_get_level()) {
        ob_end_flush();
    }
}, 999);

This method is mostly intended to crack down on inline script execution. Therefore you should also add another header rule in the WP Engine to account for wp-content and wp-includes files for which the header we defined with code above may not be sent when they’re accessed directly.

This is where the conditions to refine rules come in handy. They let you apply CSP rules to specific parts of your site. Furthermore, all of them must be true for the rule to be sent. This helps target certain pages or urls without affecting your entire site.

Real-world condition example

Here’s how to target WordPress core directories:

  • Type: URI (web address)
  • Operator: Regex matches
  • Value: ^/(wp-content|wp-includes).*

This rule only applies to WordPress content and includes folders.

Common WordPress patterns
  • ^/wp-admin.* targets the admin area only
  • ^/wp-login.php affects just the login page
  • ^/(wp-content|wp-includes).* covers WordPress core files
Available condition types
  • URI conditions: Target specific web addresses
  • IP address conditions: Control access by location
  • User agent conditions: Target specific devices or browsers
  • Header conditions: Advanced targeting options
Best practices

Rules are read top to bottom – order matters. Put exception rules before general rules and always test conditions carefully before going live.

Conclusion

Implementing content security policy strengthens your site’s defense against common attacks like cross-site scripting and code injection. While the process requires careful planning and testing, WP Engine’s Web Rules settings make CSP configuration straightforward and manageable.

Start with basic policies, test thoroughly on staging, and gradually refine your rules using conditions when needed. Remember that some WordPress functionality may require security compromises like ‘unsafe-inline’, but the overall protection CSP provides far outweighs these trade-offs.

BoostBuddy.io

Stay ahead with fast and optimized website that converts better!

OR

Get the complete performance checklist for just $20 $169 here!