Table of Contents [TOC]
So you scanned your website and it shows that Not all recommended security headers are installed. You want to Add HTTP Security Headers in WordPress? Confused?
In this post, we’ll look at why WordPress HTTP security headers are useful, how they can help improve the security of your site, and how to add HTTP Security Headers in Your WordPress site easily via htaccess and plugins.
HTTP security headers allow you to add an extra layer of security to your WordPress website. They can help block common malicious activity, including clickjacking, XSS attacks, and more.
People often ask
WordPress security is an aspect that is often neglected very lightly, thinking that hacks and attacks always happen “to others” without thinking that the next “other” may be ourselves. That is why whenever we can, we dedicate an article to increase the security of your websites.
Even so, it never hurts to increase the security of our project through our own means. A clear example of this is the insertion of HTTP security headers in WordPress.
Before diving into security headers, learn about known threats on the web and why you’d want to use these security headers.
The good news is that they’re both free and easy to implement. The bad news is that if you don’t have them already, then your site is vulnerable right now!
You can implement HTTP security headers in two main ways:
Using a plugin – These plugins make it easy for you to configure each header without having to manually edit any code
Manually editing .htaccess on Apache, nginx config or web.config on IIS – This is more technical and requires more effort but if you already have experience with these files then this would be a great option for you
In this article we’ll explain what WordPress HTTP security headers are, what they can do to protect your website and how to add security headers in a WordPress site.
When you visit a website, the browser makes a request to the webserver that hosts it. Immediately afterward, the webserver responds with another request that contains headers (the so-called response headers).
These headers contain information about the cache control, the type of content to be displayed in the browser, how said content is encoded, what time the connection was made and more.
Basically, HTTP headers are a set of rules that provide information on how browsers should behave when delivering content. These headers can be used by the server or client (in this case the browser).
When you make an HTTPS request, your browser asks the server for information by sending a series of requests and headers. The server then responds with a status code in the header, followed by a series of response headers and then the body of the document.
If we increase the security of these security headers, we will add a More layer of security on our website that will help mitigate possible attacks and vulnerabilities.
The problem with all this is, to access these files and edit them, we will have to request it from our web hosting company since they are very delicate files of the Apache, NGINX, and other configuration.
HTTP security headers are a feature of your web server and not specific to WordPress. They give you the ability to configure some additional security measures that can be applied when someone attempts to access a resource on your website (such as a page or an image).
Security headers allow you to add an extra layer of security to your WordPress website. They can help block common malicious activity, such as cross-site scripting attacks and clickjacking attempts.
Http Security Headers will set the following response headers:
"X-Frame-Options" - Set to "SAMEORIGIN".
This will prevent the page from being loaded in a frame, iframe or object. This protects your site from Clickjacking attacks.
"X-Content-Type-Options" - Set to "nosniff".
This will prevent Internet Explorer and Google Chrome from MIME-sniffing a response away from the declared content-type. This also helps protect against drive-by download attacks and sites serving user uploaded content that, by clever naming, could be treated by MSIE as executable or dynamic HTML files.
"X-XSS-Protection" - Set to "1; mode=block".
Provides XSS protection by setting the X-XSS-Protection header. This is usually enabled by default in modern browsers.
"Strict-Transport-Security" - Set to "max-age=31536000;
includeSubDomains; preload”; tells the browser that it should only
Simply run a security scan below. WP hacked help is the only AI based wordpress security scanner tool that will show you all the missing security headers on your wordpress site alongwith many other details. Our AI WordPress vulnerability scanner scans and exposes vulnerabilities, malware and provides a report of the findings
This tool will analyse the HTTP response headers of a website and adds a rating system to the results.
There are a lot of different HTTP security headers that you can use with your WordPress site, but we’re going to look at the most important ones and show you how to set them up. Let’s have a look at wordpress security headers that will give your site some much-needed protection:
The HTTP Strict Transport Security (HSTS) header lets you tell the browser that it must never load your site using HTTP and must instead use HTTPS. It also tells the browser to remember this for a specified amount of time. By using this header, you ensure that your website is always loaded over HTTPS.
If you have moved your WordPress website from HTTP to HTTP, this security header allows you to prevent browsers from loading your website over HTTP.
X-XSS-Protection is used to configure cross-site scripting (XSS) protection in the browser. It helps prevent some types of XSS attacks on your site by preventing the browser from rendering the page if an attack is detected.
The X-Frame-Options security header prevents cross-domain iframes or click-jacking. The X-Frame-Options header can be used to prevent various DDOS attacks and brute force attacks too, on your wordpress website. It allows you to tell the browser whether or not a page on your site can be embedded using iframe elements.
X-Content-Type-Options blocks mime-type content sniffing.
Let’s learn about these HTTP security headers in detail and why they are so important.
⭐Cross-Origin-Embedder-Policy | allows a site to prevent assets being loaded that do not grant permission to load them via CORS or CORP. |
---|---|
⭐Cross-Origin-Opener-Policy | allows a site to opt-in to Cross-Origin Isolation in the browser. |
⭐Cross-Origin-Resource-Policy | allows a resource owner to specify who can load the resource. |
We will take a closer look at the different HTTP security headers and how you can easily implement them on your WordPress site. Next, we will explain to you in broad strokes, what each of these headers does:
Let’s say you have an example.com site, and you set up an SSL / TLS certificate to go from HTTP to HTTPS.
Using strict transport security (HSTS), you can force the latest web browsers like Google Chrome, Firefox, and Safari to communicate with your website over HTTPS only.
X-XSS, also known as cross-site scripting, is a security header that protects sites against cross-site scripting.
By default, this security header is integrated and active in modern web browsers. This security header will not let a page load if it detects a cross-site scripting attack.
The X-Content-Type-Options is a kind of security header that prevents Google Chrome, Internet Explorer, and Firefox from MIME-Sniffing a response other than the declared content type.
This security header protects content and reduces the risk of unauthorized downloads.
It has tons of possible settings and parameters but the most common parameter is nosniff.
The x-frame-options header protects websites against click theft by not allowing iframes to be filled in on your website. It is compatible with IE 8+, Chrome 4.1+, Firefox 3.6.9+, Opera 10.5+, and Safari 4+.
In this method, an attacker tricks the user into clicking something that is not there. A user may believe that he is on the main site; however, there is something else running in the background. In this way, hackers can steal information from your web browser.
Cross-Site Scripting (XSS) is a type of attack that allows malicious scripts to be injected and executed in a vulnerable website.
Content-Security-Policy
provides an added layer to mitigate XSS attacks, it helps reduce the risk of XSS attacks in modern browsers by declaring which dynamic resources are allowed to load and from where.
Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement to distribution of malware.
To enable CSP, you need to configure your web server to return the Content-Security-Policy HTTP header. Ref – https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
When a user visits a website, a “Referrer” header is immediately included that informs the server where the visitor comes from. This header is used for statistical purposes.
As you understand, this presents a personal privacy issue.
The feature-policy is a kind of security header that allows web owners to allow and deny certain functions of the web platform on their own pages and in which they embed.
Using the feature-policy header, as a site owner you can restrict browser features.
For each of the characteristics, you must specify what is allowed and what is not. These are the possibilities:
For example, if you want to disable geolocation and camera on your WordPress site, you have to define a feature-policy like this:
Feature-Policy: geolocation ‘none’; camera ‘none’
Specifying the parameter ‘none’ in the source list will disable this functionality.
You can configure HTTP security headers in a number of ways. You can use a plugin, you can use .htaccess or Nginx config files, or you could configure them in your application code. For WordPress websites, it’s best to use a plugin to configure HTTP security headers. You can try adding new headers by inserting code in the functions.php. If it doesn’t work for you, you have very restrictive web hosting, and you will have to notify your provider.
Just drop the following code into your theme’s functions.php file.
1 2 3 4 5 6 7 | /** * Enables the HTTP Strict Transport Security (HSTS) header in WordPress. */ function tg_enable_strict_transport_security_hsts_header_wordpress() { header( ‘Strict-Transport-Security: max-age=31536000’ ); } add_action( ‘send_headers’, ‘tg_enable_strict_transport_security_hsts_header_wordpress’ ); |
This adds the Strict Transport Security header for 1 year, which is required if you want to eventually be eligible for HSTS preloading in browsers like Chrome, Firefox and Safari.
Before manually adding these files you will need to access your .htaccess file. This file only available on Apache servers via FTP.
Before uploading, make sure you have a back-up of your current .htaccess file. As an example:
This procedure lets you configure HTTP security headers in WordPress at the server level. It requires you to edit the .htaccess file on your site. This is a server configuration file used by the most widely used Apache web server software.
Simply log into your site using an FTP client or the file manager application in your hosting control panel. In the root folder of your site, you must place the .htaccess file and edit it.
This will open the file in a plain text editor. At the bottom of the file, you can add the code to add HTTPS security headers to your WordPress site. You can use the following sample code as a starting point, set the most commonly used HTTP security headers with the optimal settings:
Strict-Transport-Security header set “max-age = thirty-one million five hundred thirty-six thousand” env = HTTPS X-XSS-Protection header set “1; mode = block ”X-Content-Type-Options header set nosniff X-Frame-Options header set DENY header set referrer policy: no-referrer-when-downgrade
<ifModule mod_headers.c>
Header set Strict-Transport-Security “max-age=31536000” env=HTTPS
Header set X-XSS-Protection “1; mode=block”
Header set X-Content-Type-Options nosniff
Header set X-Frame-Options DENY
Header set Referrer-Policy: no-referrer-when-downgrade
</ifModule>
Remember to save your changes and visit your site to make sure everything is working as expected.
Note: Wrong headers or clashes in the .htaccess file can cause 500 internal server failures on most web servers.
Cloudflare offers a basic free website firewall and CDN service. Their free plan lacks advanced security features, so you’ll have to upgrade to their more expensive Pro plan.
To add Cloudflare to your site, check out our tutorial on how to add a free Cloudflare CDN in WordPress. Once Cloudflare is active on your website, navigate to the SSL/TLS page under your Cloudflare account dashboard, then switch to the Edge Certificates tab.
Now scroll down to the HTTP Strict Transport Security (HSTS) section and click on the “Enable HSTS” button. This will bring up a popup with instructions telling you that you need to enable HTTPS on your WordPress blog before using this feature.
Click the Next button to continue and you will see options to add HTTP security headers. From here you can enable HSTS, no-sniff header, apply HSTS to subdomains (if they use HTTPS), and preload HSTS.
This method provides basic protection using HTTP security headers. However, it doesn’t allow you to add X-Frame-Options and Cloudflare doesn’t have a UI to do so.
You can still do this by creating a script using the Workers function. However, creating an HTTPS security header script can lead to unexpected problems for beginners, so we don’t recommend it.
Yes, there are also plugins for WordPress that allow you to add HTTP security headers in WordPress. These are some of those available for free:
Content Security Policy Manager is a WordPress plugin that allows you to easily configure Content Security Policy headers for your site. You can have different CSP headers for the admin interface, the frontend for logged in users, and the frontend for regular visitors.
The Security Headers plugin by WP-Spies allows you to easily set up HTTP security headers without needing to know anything about code or server configuration files. The plugin is simple and only requires you to activate, then click a button to configure the default settings. Once activated, the plugin will give you the option to keep all of the default settings or change them according to your needs.
If you want more control over the plugin, you can also install their companion plugin called Configure Security Headers which gives you more advanced options for configuring specific settings on your WordPress website.
It is extremely lightweight and works automatically out-of-box.
Unlike many other plugins that are hard to configure or use. This one is made to work on all sites and without any settings or configurations.
Upon activation, the plugin will show a setup wizard that you can just follow along to set up the plugin. After that, go to Tools » Redirection page and switch to the ‘Site’ tab.
Next, you need to scroll down to the bottom of the page to the HTTP Headers section and click on the ‘Add Header’ button. From the drop-down menu, you need to select the ‘Add Security Presets’ option.
After that, you will need to click on it again to add those options. Now, you will see a preset list of HTTP security headers appear in the table.
These headers are optimized for security, you can review them and change them if needed. Once you are done, don’t forget to click on the Update button to save your changes.
You can now visit your website to make sure that everything is working fine.
install them and use the one that seems most intuitive to you when configuring the different parameters.
What security headers you want to add would depend on a few things & your requirements.
E.g., for Content Security Policy, you need to figure out the allowed sources/domains for scripts execution. Do back up your .htaccess file before making any changes to it.
Are you gettting this message – Your .htaccess file does not contain all recommended security headers.
A 2 step Workaround for this is –
On doing this, your site will keep on security lock icon, and the “Not all recommended security headers are installed” on the site health will be gone.
Without a referrer policy, every time a user clicks a link that takes him to another origin (domain), the browser will add a referer header with the URL from which he is coming from. That URL may contain sensitive information, such as password recovery tokens or personal information, and it will be visible that other origin. For instance, if the user is at example.com/password_recovery?unique_token=14f748d89d
and clicks a link to example-analytics.com
, that origin will receive the complete password recovery URL in the headers and might be able to set the users password.
This problem can be fixed by sending the header Referrer-Policy with a secure and valid value. There are different values available, but not all are considered secure. Please note that this header only supports one directive at a time. The following list explains each one and it is ordered from the safest to the least safe:
no-referrer
: never send the header.same-origin
: send the full URL to requests to the same origin (exact scheme + domain)strict-origin
: send only the domain part of the URL, but sends nothing when downgrading to HTTP.origin
: similar to strict-origin without downgrade restriction.strict-origin-when-cross-origin
: send full URL within the same origin, but only the domain part when sending to another origin. It sends nothing when downgrading to HTTP.origin-when-cross-origin
: similar to strict-origin-when-cross-origin without the downgrade restriction.You can define a Content Security Policy by setting a header in your application. The header can look like this:
Content-Security-Policy: frame-ancestors 'none'; default-src 'self', script-src '*://*.example.com:*'
In this example, the frame-ancestors directive set to ‘none’ indicates that the page cannot be placed inside a frame, not even by itself. The default-src defines the loading policy for all resources, in this case, they can be loaded from the current origin (protocol + domain + port). The example sets a more specific policy for scripts, through the script-src, restricting script loading to any subdomain of example.com.
The policy can be with different directives, and there are other less strict options for the directives above.
Clickjacking is when an attacker a hidden iframe with multiple transparent or opaque layers above it, to trick a user into clicking on a button or link on the iframe when they were intending to click on the the top level page. Thus, the attacker is “hijacking” clicks meant for the top level page and routing them to the iframe.
The recommended way to prevent clickjacking is to send a header that instructs the browser to not allow arbitrary framing, typically from other domains.
The current recommendation is to use the Content-Security-Policy HTTP header (CSP) with a frame-ancestors directive. This header obsoletes the X-Frame-Options HTTP header.
To use CSP you need the following header:
Content-Security-Policy: frame-ancestors 'none'
The header might contain more directives, and there are other less strict options for the frame-ancestors directive.
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
A third directive, ALLOW-FROM is no longer supported by modern browsers.
If you specify DENY, all attempts to load the page in a frame will fail. SAMEORIGIN will allow the page to be loaded in the site including it in a frame is the same as the one serving the page.
The most common option is DENY when there is no need to load your pages on some other site.
Framework – PHP
To fix this issue, you need to disable TLS 1.1. We also recommend that higher TLS protocol versions are enabled, ideally version 1.2 and above.
For most systems, enabling or disabling TLS versions requires a change on the web server configuration file. Therefore, refer to your web server documentation on how to do that.
If you are using Nginx, you may use the following snippet as a guideline:
server {
listen 443 ssl;
...
ssl_protocols TLSv1.2 TLSv1.3;
...
}
If using an Apache server, please refer to the following example:
<VirtualHost *:443>
...
SSLProtocol -all +TLSv1.2 +TLSv1.3
...
</VirtualHost>
Note that we are enabling TLS 1.2 and above, reflecting our ideal scenario.
If you need to cater to clients with very old TLS support, such as ancient mobile devices, and know what you are doing, you can keep TLS 1.1 enabled, despite the known weaknesses. These issues are not as serious as the SSL protocol weaknesses, but you should weigh the need to support older clients with the risk of exposing private data. Moreover, keep in mind that TLS 1.2 support is well over 95%.
The application does not force users to connect over an encrypted channel, i.e. over HTTPS. If the user types the site address in the browser without starting with https, it will connect to it over an insecure channel, even if there is a redirect to HTTPS later. Even if the user types https, there may be links to the site in HTTP, forcing the user to navigate insecurely. An attacker that is able to intercept traffic between the victim and the site or spoof the site’s address can prevent the user from ever connecting to it over an encrypted channel. This way, the attacker is able to eavesdrop all communications between the victim and the server, including the victim’s credentials, session cookie and other sensitive information.
The application should instruct web browsers to only access the application using HTTPS. To do this, enable HTTP Strict Transport Security (HSTS).
You can do so by sending the Strict-Transport-Security
header so that browsers will always enforce a secure connection to your site, regardless of the user typing https in the address.
An HSTS enabled server includes the following header in an HTTPS response:
Strict-Transport-Security: max-age=15768000;includeSubdomains
Please bear in mind that only HTTPS responses should have the HSTS header, because browsers ignore this header when sent over HTTP.
When the browser sees this, it will remember, for the given number of seconds, that the current domain should only be contacted over HTTPS. In the future, if the user types http:// or omits the scheme, HTTPS is the default. In this example, which includes the option includeSubdomains
, all requests to URLs in the current domain and subdomains will go over HTTPS. When you set includeSubdomains
make sure you can serve all requests over HTTPS! It is, however, important that you add the option includeSubdomains
whenever is possible.
Instead of changing your application, you should have the web server setting the header for you. If you are using Apache, just enable mod_headers
and add the following line to your virtual host configuration:
Header always set Strict-Transport-Security "max-age=15768000;includeSubdomains"
If you are using NGINX, just add this line to your host configuration:
add_header Strict-Transport-Security max-age=15768000;includeSubdomains
Note that because HSTS is a “trust on first use” (TOFU) protocol, a user who has never accessed the application will never have seen the HSTS header, and may therefore be vulnerable to aforementioned SSL stripping attacks. To mitigate this risk, you can optionally ask the browser vendors to include your domain in a preloaded list, included in the browser, and afterwards add the ‘preload’ flag to the HSTS header.
Once you’ve added HTTP security headers, it doesn’t hurt to check that they are working correctly.
A great place to quickly check is securityheaders.com. You just have to put the URL of your site, and it will show you immediately if you have HTTP security headers and which ones.
You may also want to see our complete WordPress security guide, and our expert pick of the best WordPress plugins to secure your site in 2024.
We have worked around several topics dealing with WordPress and the different ways you could optimize your web page.
If you have a WordPress website you must be strict with the security of your site. To successfully run a blog, business, or online store, you need to make sure your site is completely secure.
Customers visit your website, buy products and pass sensitive information such as passwords, credit card details, etc. If there is a place to infiltrate your website, then hackers can steal your customers’ data.
When it comes to website security, there are many things you can do to strengthen WordPress security.
A good place to improve the security of your website is to add HTTP security headers to your WordPress website to ensure that you stay up to date with the best security practices.
We hope this article has helped you learn how to add HTTP security headers in WordPress.
We worked around several topics dealing with WordPress and the different ways you could strengthen the security of WordPress.
For example, 21+8 Best WordPress Security Tips & Tricks 2024, read the updated post today.