Home Blog WordPress Security How to configure WordPress Content Security Policy Headers

How to Configure WordPress Content Security Policy Headers

How to configure WordPress Content Security Policy Headers

There are many ways to tighten up security on your WordPress site. Establishing a strict Content Security Policy is one method that should not be overlooked.

Implementing a CSP can significantly reduce the risk of cross-site scripting (XSS) and other attacks that could harm your website and its visitors. By controlling which resources a browser is allowed to load, you can prevent bad actors from exploiting vulnerabilities.

If you’re not sure what a WordPress content security policy is or how to set one up, this guide is here to help. We’ll explain everything you need to know about CSPs and multiple ways to implement them.

What are WordPress HTTP security headers?

Before we explain Content Security Policies, you need to understand WordPress HTTP security headers. These headers tell the browser how to behave when handling your WordPress site’s content.  And they add an extra layer of security by blocking vulnerabilities from being exploited.

There are several types of HTTP security headers.

  • HTTP Strict Transport Security (HSTS): Forces the browser to use the secure HTTPS connection. You’ll no longer be able to use HTTP connections as a fallback. But this prevents SSL stripping attacks that redirect users to the insecure version of your website.
  • X-Content-Type-Options: Prevents the browser from MIME-sniffing the content type of a file. MIME-sniffing is when browsers attempt to detect a file’s type (image, text, HTML, executable, etc.) based on its contents. But some attackers manipulate this to execute malicious code embedded in seemingly innocuous files.
  • X-Frame-Options: Provides clickjacking protection by preventing the page from being displayed in a frame or iframe. Some malicious websites use iframes to embed your website’s content. Then they trick users into clicking on something unwanted.
  • X-XSS-Protection: This one is deprecated and built into most modern browsers now. It detects cross-site scripting attacks and prevents them from executing.

And finally, there’s the Content Security Policy, another type of HTTP security header.

What is a Content Security Policy (CSP)?

While general HTTP headers address a variety of different security issues, the Content Security Policy focuses on securing a site from content-based vulnerabilities, including data injection and cross-site scripting attacks.

The CSP is solely focused on specifying which dynamic resources are allowed to load and execute on the webpage. It may specify which scripts can be executed, which domains can be used for image sources, and restrictions on certain CSS functionality.

A CSP for WordPress is a very powerful way to control where content on your site can come from. It also controls what sort of scripts are allowed to execute. XSS and code injection attacks struggle to get around these policies.

By only whitelisting particular sources using WordPress security headers, you block unknown scripts and content from being able to execute.

What is a content security policy header?

A content security policy header is an HTTP response header that helps improve the security of a website. Anyone can add HTTP security headers to their website, and define various directives to control different types of resources like CSS or JavaScript. These directives can be adapted to your individual environment. So, it’s a useful and versatile way to mitigate content-based vulnerabilities.

Why your website needs a CSP

When it comes to securing your website, it’s best to be proactive. Would you rather spend hours or days cleaning up a malware-infected website, or stop the attacks before they can do any harm?

Implementing a Content Security Policy is a great way to stop potential exploits in their tracks.  And there are quite a few exploits that a CSP can help protect against. Let’s explore a few.

Cross-site scripting (XSS)

Cross-site scripting is one of the most common security vulnerabilities on the web, and WordPress sites are no exception. XSS attacks occur when attackers inject malicious scripts into your web pages.

The results can be devastating. “Cookie stealing” allows attackers to hijack user sessions – potentially granting them admin access. Other vulnerabilities allow them to deface your website and fill it with malware and spam links.

A CSP effectively mitigates the risk of XSS attacks by specifying which sources the browser is allowed to load scripts from. Only scripts from trusted sources can be executed, and all others will be blocked from running. Your CSP can also block inline scripts and event-handling HTML attributes, which are common vectors for executing XSS attacks.

This isn’t foolproof, especially when you have a lot of plugins adding more potential scripting vulnerabilities, but a CSP will block the majority of XSS attempts.

Data injection attacks

Data injection attacks occur when an attacker inserts malicious data into your website, usually by exploiting insecure input validation such as form submissions. Many WordPress users who install form plugins without proper input sanitization are unfortunately familiar with code injection attacks.

A successful data injection attack could result in your database being manipulated, users being redirected to malicious websites, or spam being displayed on your website. SQL injection and form tampering are two common manifestations of the data injection attack.

Your Content Security Policy protects against this by controlling what data can be loaded and executed, so user inputs or compromised third-party resources won’t be able to do harm to your site.

As WordPress websites are full of dynamic content and sources of user input, they’re particularly vulnerable to this kind of attack. A CSP is necessary to mitigate it.

Packet sniffing attacks

A packing sniffing attack involves attackers intercepting data packets as they travel across a network ((https://us.norton.com/blog/emerging-threats/packet-sniffing-attack)). This can expose sensitive information such as passwords, session tokens, or credit card numbers – and if your site is not enforcing HTTPS, this data is transmitted in plain text rather than being encrypted.

Within your Content Security Policy, it’s possible to enforce secure connections through one of its directives. Upgrading these insecure HTTP requests to HTTPS ensures that all data transmitted to and from your website is encrypted. Even if attackers get ahold of sensitive info, it will be encrypted. Then it’s useless to them.

A CSP only indirectly helps with packet sniffing attacks. It doesn’t prevent them. Rather, it just reduces the impact.

Clickjacking

Clickjacking is when attackers trick users into clicking on something they didn’t want to. Usually, something is hidden on top of another web element ((https://owasp.org/www-community/attacks/Clickjacking)). The effects of this range from simply liking a social media post to turning on your webcam. It can also grant access to sensitive information or redirect to another website.

For example, users may attempt to click a button on a website, not realizing that a transparent iframe is layered on top of what seems to be a harmless web element. When you click this iframe, you’re redirected to a malicious website.

A CSP combats clickjacking with a directive that prevents other domains from embedding your website’s content within iframes. No other website will be able to frame your content without permission, preventing attackers from misleading users.

This is a similar but more powerful version of what the older X-Frame-Options HTTP header can do.

File inclusion attacks

In a file inclusion attack, bad actors exploit vulnerabilities in a web application to execute malicious code. In WordPress, these attacks typically exploit poorly secured plugin or theme files. This allows attackers to inject PHP code into your server or run malicious scripts in your users’ browsers. This is made especially easy if you haven’t done any PHP code hardening.

Implementing a CSP can greatly reduce the risk of some types of file inclusion attacks. By defining strict policies that restrict what scripts can be loaded and executed on your site, even if an attacker manages to inject a malicious file, the browser will block it from running.

How to create a Content Security Policy

Now that you know why a CSP is such an important part of any website’s security plan, you’re probably wondering how you can add one to WordPress.

This should only be done if you’re familiar with WordPress’ back end and have at least some technical knowledge. Some troubleshooting is also often required, so time and patience can help you get through it.

Deploying a CSP will take a few steps, starting with identifying the sources of scripts on your website, defining directives, and adding the policy into WordPress.

Step 1. Identify your site’s resources

Before anything, you need to identify and catalog all the external resources that your site relies on. This includes scripts, stylesheets, images, fonts, media files, and frames.

To create a CSP that isn’t so strict that it blocks media your website needs to function – like its primary font or its CSS stylesheet – you’ll need to figure out where those resources are loading from.

One way to do this is to use your browser’s built-in Developer Tools. Chrome, Firefox, and Edge all have tools like this.

  1. Go to your website. Right-click the page and select Inspect. Or try pressing F12 or Ctrl+Shift+I on your keyboard. A developer menu will pop open.
Website inspector

2. Click the Network tab. Refresh the page and watch it populate with new entries.

Website inspector Elements option

3. Take note of the scripts, images, stylesheets, and so on that your site calls on, and create a list of “safe sources” that will need to be whitelisted. Check for external libraries or resources you might be loading from third-party services like Google Fonts, CDNs, or analytics.

Website inspector Network tab

You can also manually check your site’s HTML for tags like <script>, <link>, and <iframe> and any sources within. An easy way to do this is to right-click the page and click View page source.

Website page source

Or you can use a Content Security Policy Generator, which will harvest the data from your site and output an appropriate CSP based on the external scripts used on your site.

Step 2. Define CSP directives

Once you have a clear understanding of your site’s resources, the next step in crafting your CSP is defining the appropriate directives. These are the actual set of instructions which tell the browser how to handle internal and external resources on your website.

HTML headers

Here are some of the most commonly used CSP directives:

  • default-src: This is the fallback directive. If no other directive is applicable, default-src is used.
  • script-src: Defines valid sources for JavaScript. This includes not only URLs from which scripts can be loaded but also options like ‘unsafe-inline’ which allows inline scripts.
  • style-src: Specifies valid sources for stylesheets. Similar to script-src, this can include specific URLs, as well as ‘unsafe-inline’ to allow inline styles.
  • img-src: Controls where images can be loaded from.
  • connect-src: Specifies the allowed sources for XMLHttpRequest, WebSocket, and EventSource connections.
  • font-src: Defines which sources can serve fonts.
  • frame-src: Specifies valid sources for framing (iframes). This is crucial for preventing clickjacking attacks.
  • report-uri / report-to: A URI where reports will be sent if the CSP is violated.

The Content Security Policy Reference is a great resource of all CSP directives and how to use them.

You also need to know how to configure these references. Here are a few common sources.

  • none: No resources will be loaded, even from your own website.
  • self: Only resources from your own website will load.
  • example.com: Allow loading resources from a particular domain. You can also specify subdomains or use a wildcard (*.example.com would allow loading from any subdomain on example.com).
  • https: Only load HTTPS resources from any allowed domain.

A CSP directive that only loads scripts from your website and Google APIs would look like this:

script-src 'self' https://apis.google.com;

When defining your directives, be as specific as possible to limit potential attack vectors, but ensure that you don’t break your website by being too strict. Luckily, if you do make a mistake with your CSP, it’s easy to roll back and try again.

Step 3. Add a Content Security Policy to WordPress

Once you’ve set up your CSP, it’s time to integrate it into your WordPress website. There are several ways to do it, some simpler than others. Here’s a breakdown of the most common approaches.

Use meta tags to add a CSP

If you plan on implementing a simple policy, or you just want to test out a CSP, you can use meta tags. This is the easiest way to do it, but has some limitations. For example some directives (report-uri) won’t work, and it possibly won’t affect external scripts handled by your server.

  1. Open your Theme Editor through Tools > Theme File Editor (or Appearance > Theme File Editor) in the WordPress dashboard.
WordPress theme file editor

2. Look for the header.php file for your theme. If your theme lacks one, you may want to instead use a plugin like Insert Headers and Footers.

3. Insert a meta tag like this within the <head> section:

<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src ‘self’ https://example.com; script-src 'self';">
WordPress theme header

Replace the example above with your own policy.

Add a CSP with Apache

If your WordPress site runs on an Apache server, you can add your CSP directly to your .htaccess file. This method applies the CSP site-wide, which is more secure than using meta tags.

There are two ways to do this: You can either download an FTP client like FileZilla to access your website, and look for .htaccess in the top-level directory. Or you can log in to your web host’s cPanel (or equivalent).

  1. Login to cPanel and click File Manager.
cPanel File Manager

2. Search for .htaccess in the list of files. Open it by clicking Edit in the top right corner.

SFTP htaccess file

Once you have .htaccess open, insert a line of code like this, replacing the example policy with your own:

Header set Content-Security-Policy "default-src 'none'; img-src ‘self’ https://example.com; script-src 'self';"

Add a CSP with Nginx

If your site instead is using an Nginx server, it’s just as easy to add a CSP, and the process is similar. Again, access your site over FTP or use your web host’s cPanel/custom panel. Here’s how to do it with cPanel:

1. Login to cPanel and open the File Manager, as outlined above.

2. Instead of .htaccess, you’re looking for nginx.conf, which is usually located in the /etc/nginx/ directory.

nginx configuration file

3. As above, click Edit in the top bar to open nginx.conf.

Once you open nginx.conf, look for the server block (“server {”) and insert this code somewhere within its brackets, replacing the example code with your own.

add_header Content-Security-Policy "default-src 'none'; img-src ‘self’ https://example.com; script-src 'self';";
nginx content security policy

Use a plugin to add a Content Security Policy

For those who prefer a more straightforward, code-free approach, there are numerous WordPress plugins that can help you set up a CSP. If you’re uncomfortable editing server files directly, this method is ideal.

There are many plugins that can help, including HTTP Headers and Headers Security Advanced & HSTS WP. We’ll show you how to use the latter, as it’s the most well-known.

From your WordPress dashboard, navigate to Plugins > Add New Plugin and search for Headers Security Advanced & HSTS WP. Install and activate it.

Headers Security Advanced plugin

Go to Settings > Headers Security Advanced & HSTS WP and scroll down to CSP Header Contents.

Fill in the box with the Content Security Policy you created.

CSP plugin configuration

Test your Content Security Policy

Once you’ve successfully implemented your CSP, the final step is to test it out and make sure everything is working. If it’s inadvertently blocking legitimate resources, it may be obvious or subtle.

Open the browser Developer Tools and check the Console for errors related to blocked resources.

Console developer tools CSP testing

Use an online CSP validator, like the Policy Evaluator or Google’s CSP Evaluator, which additionally will test if your policy has any security misconfiguration.

CSP policy evaluation

Use the report-uri or report-to directives in your CSP to gather data on policy violations. You can check this over time to see if a legitimate resource is being blocked.

Running into issues? Let’s try to fix them.

Content security policy issues and how to fix them

Implementing a CSP is not without its challenges, and getting a working policy can be a big ordeal depending on your server setup. Here are some challenges you may run into, and strategies to address them.

Inline scripts and styles

WordPress and many plugins and themes often use inline scripts and styles. CSP restricts inline executions unless explicitly allowed using the “unsafe-inline” directive, which can open up vulnerabilities. You would need to either modify the inline scripts to external files or use nonces or hashes, which can be complex to manage.

Conflicts with other plugins

Plugins often add their own scripts and external resources. With every plugin you add, you may have to modify your CSP to allow their resources. You’ll need to audit and update your CSP when installing new plugins.

Broken website functionality

A strict CSP can inadvertently block legitimate resources, leading to a broken website. Using browser Developer Tools can help you identify the broken scripts.

Incorrect header syntax

Errors in the syntax of your CSP can cause the entire policy to fail, leading to no enforcement. Utilize CSP validator tools like those listed above to check your syntax for errors.

Lack of browser support

Some older browsers don’t support CSP or some of its directives, or may interpret them differently. You may wish to implement fallback HTTP security headers like X-Frame-Options and X-XSS-Protection.

Performance issues

A complex CSP with many different allowed sources and directives can slow down your site’s performance due to having to check every single resource. It can help to use wildcards to consolidate sources. If your report-uri directive is generating tons of reports, this can also slow down your server, so make sure you fix whatever error is causing this.

HTTPS mixed content issues

If your CSP enforces HTTPS but your site still references HTTP content, browsers will block these resources, potentially breaking site functionality. Some CSP validators can identify mixed content issues, and you should ensure all content is loaded over HTTPS. The “upgrade-insecure-requests” directive can also help.

CSP for WordPress is part of a larger strategy

A Content Security Policy serves as a major safeguard against cross-site scripting attacks and all manner of other malicious attacks. One line of code can make a major difference in your website’s security.

As effective as it is, implementing a CSP is only a secondary line of defense. A comprehensive security strategy that combines multiple layers of protection is essential.

If you’re looking to improve website security further, we have several security plugins, including WP 2FA for two-factor authentication, CAPTCHA 4WP for adding CAPTCHA to your site, and Melapress Login Security for login security. Each of these can further expand your security practices and safeguard your website.

Posted inWordPress Security
Brenda Barron
Brenda Barron

Brenda is a freelance writer with over a decade of experience with web design, development, and WordPress. When not click-clacking at the keyboard, she’s spending time with her family, playing music, or taking up a new hobby.


Leave a Reply

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

Stay in the loop

Subscribe to the Melapress newsletter and receive curated WordPress management and security tips and content.

Newsletter icon

It’s free and you can unsubscribe whenever you want. Check our blog for a taste.

Envelope icon

Take the Melapress Security Survey 2024

Share your perspective
and WIN