Home Blog WordPress Security Configuring HTTP security headers on WordPress

Security Headers on WordPress

Configuring HTTP security headers on WordPress

Most modern browsers support a variety of HTTP security headers to improve the security of your WordPress website, better protect your visitors from classes of browser attacks such as clickjacking, cross-site scripting, and other common attacks, and even improve your site’s visitors’ privacy online.

This article gives an overview of what these HTTP security headers are, explains how they work and what is their scope. It also explains how you can add these HTTP security headers to your website to improve the security of your WordPress website.

What is an HTTP security header anyway?

HTTP security headers are a series of HTTP headers1 exchanged between a web client (browser) and a web server which are used to specify the security-related settings of HTTP communication between a web client and a server. Enabling security headers on your WordPress website can improve your website’s resilience against common attacks, including cross-site scripting (XSS) and clickjacking.

How HTTP security headers can improve WordPress security

HTTP security headers can help improve your WordPress website’s security by instructing the browser to enable a variety of security features accordingly. In many cases, implementing the right headers is a tricky affair and may even have different results (or be totally ineffective) in older browsers, so it is best-practice to try out any changes in a testing or staging environment before applying any changes on a live WordPress site.

The most commonly used HTTP security headers

Which headers do what? Let’s dive into an overview of some of the most important and commonly used HTTP security headers.

Strict-Transport-Security

The Strict-Transport-Security HTTP header instructs the browser to enforce HTTP Strict Transport Security (HSTS)2. An HSTS header instructs the visiting browser to always access the site over HTTPS (instead of HTTP), even if the user (or an attacker trying to run a Man-in-the-Middle attack) tries to access the site over HTTP, the browser will forcibly switch to HTTPS, even if HTTP is unavailable — to such an extent, you should only enable HSTS if you have HTTPS enabled and fully working correctly without mixed-content issues3.

The following HTTP Strict Transport Security (HSTS) HTTP response header enables HSTS for the duration of 1 year (31536000 seconds).


Strict-Transport-Security: max-age=31536000

Content-Security-Policy

The Content-Security-Policy HTTP security header is an HTTP header with a lot of power and configurability. It configures the browser’s Content-Security Policy (CSP) which is a set of security features found within modern browsers that provides an additional layer of security which helps to detect and mitigate attacks such as Cross-Site Scripting (XSS) and data injection attacks.

Content-Security Policy (CSP) is also notoriously tricky to get right since the right CSP settings will very widely depending on the website in question, and should be heavily tested before deployment — so much so, it has a sister Content-Security-Policy-Report-Only4 HTTP header used just for testing CSP.

The following is an example of a pretty simple Content-Security Policy (CSP) policy that only allows loading assets from the origin the website is served from.


Content-Security-Policy: default-src 'self'

However, Content-Security Policy (CSP) is much more configurable than shown in this simple example. CSP includes other directives such as script-src, style-src, and img-src to specify sources which the browser may load assets (for example CSS, images and fonts) from. For a full list of how CSP can be configured, see the Content Security Policy quick reference guidelines.

X-Content-Type-Options

The X-Content-Type-Options HTTP security header is a non-standard header respected by all major browsers that prevents Cross-site Scripting (XSS) attacks that are caused as a result of MIME type sniffing5. When present, this header tells the browser to strictly follow the MIME types defined in the Content-Type HTTP header, and that the browser should not try to detect the correct MIME type for the response data itself. The header has a single directive — nosniff.


X-Content-Type-Options: nosniff

Old or unused HTTP security headers

There are also a number of old and unused HTTP security headers. They are no longer used, or no longer work because they were either introduced as temporary fixes, experiments, or even non-standard initiatives that have since either been deprecated or replaced entirely. Below is a list of these HTTP security headers.

HTTP security headers replaced by Content-Security-Policy

X-Frame-Options

The X-Frame-Options HTTP security header is a now deprecated header which was first introduced by Microsoft Internet Explorer (and adopted by other browsers with varying degrees of uniformity and compatibility) to protect browsers against Cross-site Scripting (XSS), Clickjacking and other attacks that rely on a website being placed inside of an iframe.

This header has now been replaced by the frame-ancestors Content Security Policy (CSP) directive. It is advised to use CSP with the frame-ancestors directive in-place of X-Frame-Options.

X-XSS-Protection

The X-XSS-Protection HTTP security header was a non-standard header introduced to enable or disable browser protections against Cross-site Scripting (XSS) attacks. In practice, this header was frequently easy for attackers to bypass and as a result is ignored by most modern browsers as a result.

Public-Key-Pins

The Public-Key-Pins HTTP security header used to configure the Public Key Pinning (HPKP) security feature that was introduced in Google Chrome and Firefox to prevent TLS certificate spoofing. HPKP worked by having the web server provide the browser with a set of cryptographic hashes of the TLS certificate public keys the website used, which the browser would in-turn use to compare with the certificates it receives from the server in subsequent requests. The problem was that HPKP was fairly complicated to manage and frequently resulted in misconfigurations that could completely disable website access — as such, it is no longer recommended to use it.

Adding HTTP Security Headers in WordPress

HTTP security headers work best when they are configured on your web server or, where applicable, your Content Delivery Network (CDN) or Web Application Firewall. This allows them to be sent upon each request. Alternatively, while less ideal, you can use a WordPress plugin to set these headers for you.

Now that we have covered the purpose of HTTP security headers, here are a few ways in which they can be enabled on your WordPress website.

Adding HTTP security headers in WordPress using Apache HTTP Server

The following is an example of the configuration for Apache HTTP Server required to enable HTTP Strict Transport Security (HSTS), X-Content-Type-Options and a simple Content Security Policy.


<ifModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000"
Header set X-Content-Type-Options "nosniff"
Header set Content-Security-Policy "default-src 'self'"
</ifModule>

Adding HTTP security headers in WordPress using Nginx

Similarly, the following is an example of the configuration for Nginx required to enable HTTP Strict Transport Security (HSTS), X-Content-Type-Options and a simple Content Security Policy.


server {
add_header Strict-Transport-Security "max-age=31536000; always;
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "default-src 'self'" always;
}

Adding HTTP security headers in WordPress using a plugin

Alternatively, while less effective (since it relies on WordPress itself to modify headers), using a WordPress plugin might be the easiest way to add HTTP security headers to your WordPress website. Plugins such as the Redirection plugin allow you to add custom HTTP headers to your website.

How to Check HTTP Security Headers for a Website

Once you add HTTP security headers on your WordPress website, you’d want to make sure they are configured correctly and working as you expect them to. The easiest way to test this is using a free tool called Security Headers6.

Using the Security Headers tool is as simple as entering your website URL and hitting “Scan”. You’ll then be given a grade from A+ through F together with an explanation of how that grade has been determined.

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers ↩︎
  2. https://owasp.org/www-project-secure-headers/#http-strict-transport-security ↩︎
  3. https://web.dev/what-is-mixed-content/ ↩︎
  4. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only ↩︎
  5. https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing ↩︎
  6. https://securityheaders.com/ ↩︎
Posted inWordPress Security
Glenn Kouma
Glenn Kouma

Glenn has a huge passion for WordPress, has been using it for over 5 years, and even develops a couple of premium themes. Glenn enjoys blogging, music, and the outdoors. You can reach Glenn at glenn@melapress.com.


2 thoughts on “Configuring HTTP security headers on WordPress

  1. I’ve read a lot of articles about this topic but no one is going to answer a simple question which is HOW TO EXACTLY SHOULD WE DO THAT?????? WHERE SHOULD WE ADD THESE CODES? htaccess? robots.txt? server? where????? even my stupid host server doesn’t know about it!! Is anyone who can help???

    1. Hello Pedram, thank you for your comment. As explained in the article you can add headers from the web server configuration or by using a WordPress plugin. It is explained in detail in the second half of the article.

      Good luck with the implementation.


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
newsletter-pop-up