Security

How to Add Security Headers to Your WordPress Site

Increase the security of your website by adding security headers. Check your score on securityheaders.com and try to achieve an A score. There are several different ways to add security headers onto your WordPress site.

Before we continue, there’s a few things that should be noted on what they do.

strict-transport-security: Adding this will force HTTPS on the browser. Note that this will make HTTP inaccessible. Rather than redirecting from HTTP to HTTPS, it will force the browser to go directly to HTTPS instead. This is enabled by default on Reggio.

X-XSS-Protection: This blocks attacks from older browsers.

X-Content-Type-Options: This will stop the browser from trying to MIME-sniff the content. There are no risks implementing this.

X-Frame-Options: Unless your serve the site in an iframe on another website, this is good to have. It ensure people are not adding your site into an iframe elsewhere.

Referrer-Policy: Chrome will set this by default to strict-origin-when-cross-origin but still good practice to add to the header.

Permissions-Policy: This is a fairly new header and will enable or disable features a browser may have. By default, you can disable all of them which is written below. If you’d like to tweak this, you can use this generator here. You may want to tweak this if you’re running an eCommerce site for example.

Content-Security-Policy: This header allows you to whitelist only specific assets to load on the site. This is not included in our samples as it’s often difficult to manage. If you have access to control these on your own regularly, it may be worth it. However, it takes quite a bit of time and effort to get this right. There are generator tools like Report URI that does make this a bit easier to manage.

NGINX

If you have control over your NGINX settings, you’ll want to add the following:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header Referrer-Policy strict-origin-when-cross-origin;
add_header Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=();

Apache

If you have control over your Apache settings, you’ll want to add the following in your .htaccess file that’s in the root directory of your site.

<ifModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Xss-Protection "1; mode=block"
Header always set X-Content-Type-Options "nosniff"
Header always append X-Frame-Options SAMEORIGIN
Header always set Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()"
</ifModule>

At Reggio

We use Kinsta and Pressable here at Reggio for our servers. If you’re on Pressable, there’s a file called custom-redirects.php which will contain the security headers. If you’re on Kinsta, we can reach out to Kinsta to add this on the NGINX server. Below is a sample of what you would see in the file with Pressable.

<?php
header('X-XSS-Protection: 1; mode=block');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: SAMEORIGIN');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()');

WordPress Plugin Route

While you could add these security headers via a plugin, it’s best if you can implement it on the server first if your hosting provider allows it. A few plugins that add it are HTTP Headers, GD Security Headers, and WP Defender.

Scroll to Top