Home > Blog > HTTP Security Headers: The Ultimate SEO Guide

HTTP Security Headers: The Ultimate SEO Guide

by | Oct 31, 2023 | Blog

Website security has never been a ‘nice to have’. But, now more than ever, the security of sites plays a crucial role in user trust, search engine rankings, and a business’ digital continuity and reputation. However, when it comes to technical SEO and website security, many business sites consistently fall short.

In this guide, we explore why HTTP security headers are important, answer your questions, examine their impact on your site’s SEO, and give you all the knowledge you’ll need to go about implementing them correctly yourself with world examples and top tips from our in-house Senior Technical SEO Lead, Kelly Sheppard.

Looking for something in particular? Use the navigation menu below to jump ahead and find exactly the piece of guidance you’re after.

  • What is an HTTP security header?
  • The importance of HTTP security headers
  • No security headers? More security breaches
  • The SEO benefits of HTTP security headers
  • HTTP security header best practices
  • How long does it take to implement security headers?
  • Adding “Always” to your security headers
  • Getting to know your security headers
    1. The HSTS (​​HTTP Strict Transport Security) header
    2. The CSP (Content Security Policy) header
    3. The X-Frame-Options header
    4. The X-XSS-Protection header
    5. The X-Content-Type-Options header
    6. The Referrer-Policy header
    7. The Content-Type header
    8. The Permissions-Policy header
  • Implementing your security headers
    – On Apache
    – On NGINX
    – On WordPress

What is an HTTP security header?

When a user browses a website, an HTTP response is sent to/from the server. Security headers provide additional information to the browser about how to handle a particular request, acting as a directive for web applications to use to make sure that the security defences in web browsers are configured correctly.

This helps prevent man-in-the-middle attacks and keeps users safe from harm. The X-XSS-Protection header helps to prevent cross-site scripting attacks by telling the browser to block certain types of malicious code.

Other types of security headers include:

  • Content Security Policy (CSP)
  • X-Content-Type-Options
  • X-Frame-Options
  • Permissions-Policy
  • X-XSS-Protection
  • Content-Type

By using security headers, website owners can help proactively defend against attacks and other web-based vulnerabilities, whilst keeping their users and their data safe.

The importance of HTTP security headers

At the most fundamental level, the implementation of HTTP security headers plays a crucial role in safeguarding the security of your website. By adding an extra layer of protection, these headers effectively defend against various forms of attacks in which malicious individuals can gain access to your website and cause damage to your reputation, including:

  • Cross-site scripting (XSS) attacks
  • Clickjacking attacks
  • SQL injection attacks

Falling victim to such attacks due to the absence of proper security headers can have extremely severe consequences for your website’s SEO and overall reputation. Take a moment to consider what would happen if your website were to be targeted and successfully compromised by such an attack. The repercussions could be severe. Let’s take a look at a few examples, ranging from minor to serious…

  • Malicious content could be injected into your web pages
  • Google may label your site as unsafe for users
  • The media could pick up on the hack and start reporting on it
  • Visitors may lose trust in your platform, leave the site, or not buy from you anymore
  • Your hard-earned reputation may suffer irreversible damage
  • Your site may go from thousands of clicks a month to your website to virtually none

It is therefore of utmost importance to prioritise the implementation of security headers on your site to help shield your website and your valuable users from potential harm.

By adding security headers, you demonstrate a commitment to maintaining a secure online environment, which, in turn, will help your trustworthiness and SEO.

No security headers? More security breaches

Without the effective implementation of security headers, your website could, as we touched on above, be left vulnerable to attack.

And, the worst part? You might not even know about it. Several types of attack can go unnoticed, in fact. It is common for hackers to try to hide the fact that your site has been compromised so that they can carry on gathering user data and company information for their malicious intent for as long as possible.

This is why It’s important to regularly scan your site for vulnerabilities and implement any server security patches or updates as soon as they are released. In particular, you’ll need to update your CMS plugins and themes, as well as update vulnerable Javascript libraries.

Your developer should implement security headers as part of building your website, however, this is often overlooked as being a non-essential task, particularly if you have other security measures such as Cloudflare in place.

The SEO benefits of HTTP security headers

Just as E-E-A-T is a core part of Google’s ranking factors, security is critical to SEO and goes hand-in-hand with trust and authority.

If your site were to be compromised and marked as unsafe by Google, users would get a message to not visit your site from search engine results which would severely impact rankings.

As well as this, you would have to deal with the possibility of leaked customer information, and for larger companies, the media storm that would accompany such a data breach. As search engine optimisation relies heavily on user experience and trust, you can imagine the impact such an attack would have on your rankings, conversions and online presence.

HTTP security header best practices

Now that we’ve established the fundamentals of why HTTP security headers are crucial, let’s run through the best practices for their effective implementation.

The most common security headers to add to a website are:

  • HSTS (​​HTTP Strict Transport Security) header
  • CSP (Content Security Policy) header
  • X-Frame-Options
  • X-XSS-Protection
  • X-Content-Type-Options
  • Referrer-Policy
  • Content-Type

However, there are quite a few more! You can find a full list of them here at the OWASP website.

How long does it take to implement security headers?

Most security headers are easy to implement and only take around 2 minutes each (if the right guidance is followed).

The exception to this is the Content Security Policy header, which can take a lot longer to implement, as you need to account for every external script which loads on a website. On large sites, this can be a considerable amount of scripts. Chrome extensions such as Content Security Policy (CSP) Generator can help you save time, as it can build a CSP for you.

Adding “Always” to your security headers

There’s some confusion about whether you need to add “always” to your HTTP headers or not. For example:


Header always set Strict-Transport-Security “max-age=63072000; includeSubDomains”


Header set Strict-Transport-Security “max-age=63072000; includeSubDomains”


The answer is quite simple. If you want the server to always use that particular header and never change from it for all response status codes, including 404, 500 etc then use the word” always”.

In general, when it comes to security headers, it is recommended to use the “always” keyword to ensure consistent application of the security measures across all responses, including error responses. This ensures the security headers are properly enforced regardless of the response status.

It’s important to use the word “always” for the HSTS header, and also ideally for the following headers as best practice as well:

  • Content-Security-Policy
  • X-Content-Type-Options
  • X-Frame-Options
  • X-XSS-Protection*

*Please note: “Always “is only used on Apache configurations, not on NGINX.

Getting to know your security headers

Now, we’ll take you through some of the most common security header types, how to implement them, and how they keep your site safe. Feel free to bookmark this and refer back to it whenever you need a refresh.

1. The HSTS (​​HTTP Strict Transport Security) header

If you have an SS certificate then you need an HSTS header. This is arguably the most important security header out there.

The HSTS header instructs web browsers to only communicate with a website over a secure HTTPS connection, even if the user initially requests an HTTP connection. It helps prevent potential attacks by enforcing secure communication between the browser and the website.

If a user enters http://www.yourwebsite.com, the browser knows to make this into a HTTPS connection and automatically redirects the user to https://www.yourwebsite.com

HSTS & cutting out the ‘middle man’

The HSTS protects against something called a man-in-the-middle attack. A man-in-the-middle (MITM) attack is a type of cyber attack where a hacker intercepts communication between two parties who believe they are communicating directly with each other.

Once the hacker intercepts the communication, they can eavesdrop on it, change it, or even inject new messages. This type of attack is particularly dangerous, as the parties involved are often unaware that their communication has even been compromised. The hacker can then use the information obtained to commit fraud, steal funds, or gain unauthorised access to sensitive information.

There are a few different types of MITM attacks, including:

  • IP spoofing
  • DNS spoofing
  • HTTPS spoofing
  • Email hijacking

These attacks can be used to gain access to sensitive information, such as passwords, account credentials, and financial information. To prevent MITM attacks, it is important to add an HSTS header as a first line of defence.

HSTS & 307 Redirects

If an HSTS header is in place, you might see a 307 redirect (temporary redirect or internal redirect) with certain SEO tools. However, it’s still important to have the 301 redirect from HTTP > HTTPS in place behind this redirect, so that search engines also have the same experience and all SEO value is transferred, as a 307 temporary redirect means that search engines won’t update their index to your new HTTPS URL. Even with an internal 307 redirect, that happens at a browser rather than server level, so search engines wouldn’t be able to see it.

If your site is down for maintenance, then you can change the 307 internal redirect to a 307 temporary redirect while it’s being worked on, just remember to change it back!

How to implement HSTS security headers

Here’s an example of what an HSTS security header looks like:

Strict-Transport-Security: max-age=31536000


In Apache, you want to set it to the following in your httpd.conf file:

Header always set Strict-Transport-Security max-age=31536000


With NGINX, you can add this into the nginx.conf file under server (SSL) directive:

add_header Strict-Transport-Security “max-age=31536000”;


With Cloudflare, you can:

  • Log in to Cloudflare and select the site
  • Go to the “Crypto” tab and click “Enable HSTS.”

The “max-age” tells the browser to only access this website using HTTPS for the next year, which is the ideal setting to use.


If you have subdomains, you need to ensure that they are also included in the SSL certificate and are served over HTTPS, with 301 redirects in place. You’ll need to modify the header to this:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload


Hijacking the first redirect

However, even with an HSTS header added, there is still the initial first HTTP > HTTPS redirect (before the HSTS header kicks in) which could be hijacked.

To prevent this, you could add your website to the HSTS preload website. However, there are a few prerequisites before doing so:

  • A valid SSL certificate should be installed
  • Your website and all its subdomains should be served over HTTPS
  • All 301 redirects should be in place for HTTP > HTTPS
  • Implement the following HSTS header:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload


Then you need to go to the hstspreload.org website and register your site there. As an added bonus, this can also make your site slightly faster!

2. The CSP (Content Security Policy) header

The Content Security Policy header allows website owners to specify which content sources (such as scripts, stylesheets, or images) are allowed to be loaded and executed on their web pages.

By defining a policy, it helps mitigate the risks of cross-site scripting (XSS) attacks and other code injection vulnerabilities by blocking unauthorised or malicious content. A CSP header instructs the browser to only download resources from a set group of domains and only from those domains. So if you’re not on the list, you’re not coming in!

An example would be an external script from a site like Facebook or images from another external website which are loaded onto your site. Here’s a basic example:

Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘unsafe-inline’; img-src ‘self’ data:


This header specifies that content (scripts and images) should be loaded only from the same domain (‘self’), allowing inline scripts and images loaded via data URLs. This is a very short CSP example, as many CSP’s can run into hundreds of lines for larger websites.

The Mozilla website has a lot of useful information about CSP and various examples.

How CSP headers protect your site

The CSP protects against something called cross-site scripting (XSS) attacks as well as packet sniffing attacks.

    • A cross-site scripting (XSS) attack is a type of security vulnerability that allows attackers to inject malicious scripts into websites. This is usually done by exploiting a vulnerability in the website’s code or by tricking users into clicking on a link that contains the malicious script. Once the script is executed, it can steal sensitive data such as login credentials, credit card information, and personal data.
  • Packet sniffing attacks, (also known as network sniffing or protocol analysis), involve intercepting and analysing the traffic between two or more devices connected to the internet. This type of attack is often used to steal sensitive information such as login credentials, credit card information and other sensitive data. Attackers can use packet sniffers to capture and analyse data packets that are transmitted over a network, allowing them to see the contents of those packets and potentially extract sensitive information. To prevent packet sniffing attacks, network administrators can use encryption protocols such as HTTPS, SSL/TLS, and VPNs to secure network traffic and ensure that sensitive information is protected, as well as implementing a Content Security Policy HTTP header.

How to implement CSP headers

This is one of the hardest security headers to implement, and it can take a lot of time and tweaking to get it right. In fact, not all browsers support CSP for this reason.

From experience, external sites often change the names of their files. For example: different versions of the same filename, so a CSP can be a difficult thing to keep up to date if it is explicitly set per filename. A better option is to allow scripts from certain domains so that if the filename changes, the CSP will still work.

Chrome extensions like Content Security Policy (CSP) Generator can write your CSP for you, all you need to do is navigate to the different types of pages on the site, and the extension does the rest.

Chrome's Content Security Policy generator.

You can also choose to write the policy yourself (although you will need a developer to help you). Here’s a breakdown of the different parts of a CSP header for the keen SEOs among us:

  • default-src: This is the default source for all types of resources, such as scripts, images, and stylesheets. This directive is used when no other directive is specified for a resource type.
  • script-src: This directive specifies the source for scripts, such as JavaScript, that are executed on the website.
  • style-src: This directive specifies the source for stylesheets used on the website.
  • img-src: This directive specifies the source for images used on the website.
  • connect-src: This directive specifies the source for network requests, such as AJAX requests.
  • font-src: This directive specifies the source for fonts used on the website.
  • object-src: This directive specifies the source for plugins, such as Flash.
  • media-src: This directive specifies the source for media files, such as video and audio.
  • frame-src: This directive specifies the source for frames, such as iframes.
  • child-src: This directive specifies the source for child resources, such as iframes and popups.
  • form-action: This directive specifies the source for form submissions.
  • report-uri: This directive specifies where CSP violation reports should be sent.

Each of these directives is followed by a list of sources, which can be a URL, ‘self’, ‘none’, ‘unsafe-inline’, or ‘unsafe-eval’. By using a CSP header, website owners can control what resources are allowed to be loaded on their website which stops any unauthorised resources from loading, therefore protecting users.

In Apache, you can add this to the httpd.conf file:

Header set Content-Security-Policy “default-src ‘self’;”


For NGINX you can add this to the nginx.conf file:

add_header Content-Security-Policy “default-src ‘self’;”;


CSP troubleshooting

You can deploy your CSP in “test mode” to see what will happen and if it works properly by adding a test header called Content-Security-Policy-Report-Only.

Once it’s live, check in Chrome Console for CSP errors, as it will often tell you there are issues and which resources could not be loaded and why. This means that you need to update your CSP to include these resources.

3. The X-Frame-Options header

The X-Frame-Options header helps to prevent a type of attack called clickjacking by specifying whether a web page can be displayed within an iframe on another website.

How X-Frame-Options headers protect your site

Clickjacking is a type of web attack that tricks users into clicking on something they didn’t intend to by hiding it behind a legitimate-looking page element. As an example, this can be a button in an iframe overlaying another button which is really on the website or a login form to capture login details.

Attackers often use iframes, which allow them to load a website within another website, to carry out clickjacking attacks. This is because they are effectively “invisible” and cannot be detected by a user. They are typically used to send users to another website or trick them into downloading a malicious script.

How to implement X-Frame-Options headers

You have a few different options that can be used to specify whether iframes are allowed:

  • “DENY” (prevents framing entirely)
  • “SAMEORIGIN” (allows framing only from the same origin domain)
  • “ALLOW-FROM” (allows specific origins to frame the page which you specify)

For Apache, you need to add this in httpd.conf file:

Header always append X-Frame-Options DENY


For NGINX, you need to add this within the nginx.conf under server directive/block:

add_header X-Frame-Options “DENY”;


For WordPress, you can edit wp-config.php (if comfortable doing so):

header(‘X-Frame-Options: DENY);


This header allows the web page to be displayed within an iframe, but only if the iframe’s source is from the same origin (domain).

4. The X-XSS-Protection header

The X-XSS-Protection header is used to enable the built-in XSS protection mechanism in modern web browsers, which comes as default. It instructs the browser to detect and block cross-site scripting attacks by either sanitising or blocking suspicious code embedded within web pages.

How X-XSS-Protection headers protect sites

XSS (Cross-Site Scripting) is a type of web attack where attackers inject malicious scripts into a web page. These scripts can steal sensitive information, such as login credentials or financial data. The browser’s built-in filter detects and blocks malicious scripts from executing in the user’s browser, essentially the X-XSS-Protection header just turns it on.

This setting will stop the page from being rendered if the browser detects an XSS attack. However, this header should only be considered as a last resort defence against XSS attacks. Your site should be thoroughly reviewed and built with XSS safeguards in mind to prevent injection attempts from ever reaching the browser in the first place.

How to Implement an X-XSS-Protection header

Here’s what it looks like:

X-XSS-Protection: 1; mode=block


There are 3 options you can use here:

1. X-XSS-Protection: 0 : This will disable the filter entirely.

2. X-XSS-Protection: 1 : This will enable the filter but only sanitises potentially malicious scripts.

3. X-XSS-Protection: 1; mode=block : This will enable the filter and completely block the page.

In Apache:

Header set X-XSS-Protection “1; mode=block”



add_header X-XSS-Protection “1; mode=block”;


This header enables the browser’s built-in XSS protection, which detects and blocks potential cross-site scripting attacks. This is the default mode.

5. The X-Content-Type-Options header

The X-Content-Type-Options header prevents browsers from automatically interpreting the content type of resource. When a webpage loads, it tells the browser what type of file type it is, for example, an image, a Javascript file or a HTML file. However, attackers can “fake” the file type and use that to execute malicious code, steal sensitive information, or perform other harmful actions. Sometimes browsers try to “guess” the type of content shown, like image, Javascript file, video etc. This is done to improve user experience, as often content (MIME) types are listed by developers as the wrong types or they are missing.

How the X-Content-Type-Options header can protect your site

Attackers can pretend that a file-type is a different type of file, for example an image when really it is a malicious Javascript file which downloads malware or a virus (Drive-by Download attack). This is called faking the MIME (Multipurpose Internet Mail Extensions) type. When a browser isn’t sure what a file type is (no MIME type is set, or it’s wrong), then it tries to guess what it is. This is called MIME-sniffing.

The X-Content-Type-Options header protects websites by telling the browser not to “sniff” the file and try to guess what it is, and only obey the exact MIME type specified.


It is really important that your MIME types are all correct before implementing this header, otherwise your website may not work as intended.

There are some common ones which, on older websites in particular, tend to be incorrect:

  • application/javascript should now be text/javascript
  • text/javascript 1.0 should now be text/javascript
  • vnd.youtube.yt should now be video/vnd.youtube.yt

Some common MIME types are:

  • text/html for HTML documents
  • text/plain for plain text
  • text/css for Cascading Style Sheets
  • text/javascript for JavaScript files

You can learn more about what MIME types to use on the Mozilla website, and you can see a list of all of the media MIME types on the IANA website.

How to implement the X-Content-Type-Options header

It’s very easy to implement this header, just make sure all your MIME types are correct before doing it.

It looks like this:

X-Content-Type-Options: nosniff


For Apache, you need to add this to your httpd.conf file:

Header set X-Content-Type-Options nosniff


For NGINX, it’s nginx.conf file under server block:

add_header X-Content-Type-Options nosniff;


This header prevents the browser from attempting to sniff or guess the content type, enforcing that it strictly adheres to the declared content type.

6. The Referrer-Policy header

The Referrer-Policy header determines how much information about the referring page (referrer) is included when making requests to other websites.

The Referrer header contains the URL of the page the user was on before clicking on the link, as by default, the browser sends the full URL in the Referrer header, which can potentially leak sensitive information. This can be particularly problematic if you have sensitive or financial information on your website.

How can the Referrer-Policy header protect websites?

Adding the Referrer-Policy header helps control privacy and security concerns by limiting the amount of referrer information shared with external sites. It is worth noting that this doesn’t affect affiliate links.

A good example would be a banking website, which may contain sensitive financial information within the URL, such as account numbers or previous transactions.

Here are some examples:

How to Implement the Referrer-Policy header

When implemented correctly, the Referrer-Policy header is very good at keeping customer information safe when navigating to external websites. Again, the Referrer-Policy header is pretty easy to implement. There are 3 ways you can implement this:

1. HTML for the entire document with a meta tag
2. HTML on individual elements
3. HTTP header


You can either implement it in the HTML for the entire document or for individual requests. For example, you can set the referrer policy for the entire document with a <meta> element with a name of referrer:
<meta name=”referrer” content=”origin” />

Or you can set individual requests which you can use on these elements:

  • <a>
  • <area>
  • <img>
  • <iframe>
  • <script>
  • <link>

Here’s what it looks like:

<a href=”http://example.com” referrerpolicy=”origin”>…</a>


Which sets the policy for that individual <a> tag. Whereas this one sets no referrer to the individual link, which you can use on <a>, <area> or <link> elements:

<a href=”http://example.com” rel=”noreferrer”>…</a>


HTTP Header

Alternatively, you can choose to implement this whole policy via the HTTP header. Here’s an example:

Referrer-Policy: strict-origin-when-cross-origin


There are lots of options here that you can use:

  • no-referrer: The website does not send any referrer information to the new website.
  • no-referrer-when-downgrade: This is the default value. The website sends referrer information when navigating from HTTPS to HTTP, but not the other way around.
  • same-origin: The website sends referrer information only to pages that are on the same domain.
  • origin: The website sends the origin (protocol + domain) of the referring page.
  • strict-origin: The website sends the origin of the referring page for HTTPS to HTTPS requests. For cross-protocol requests (HTTP to HTTPS), no referrer information is sent.
  • origin-when-cross-origin: The website sends the origin of the referring page for cross-origin requests, and the full URL for same-origin requests.
  • strict-origin-when-cross-origin: The website sends the origin of the referring page for HTTPS to HTTPS requests, and the full URL for cross-origin and same-origin requests.
  • unsafe-url: The website sends the full URL of the referring page, including query string and fragment. – do not use this setting as it is unsafe.

For example, setting the Referrer-Policy header to “no-referrer” would prevent a website from sending any referrer information to external websites. Setting it to “origin” would only send the domain of the referring page. The strict-origin-when-cross-origin option sends the full URL but only when the link is from the same origin as the current page.

For Apache in httpd.conf:

Header set Referrer-Policy “no-referrer”
Header always set Referrer-Policy “strict-origin”


For NGINX, it goes in the default file:

add_header Referrer-Policy same-origin;


7. The Content-Type header

The Content-Type header is used to indicate the media type (such as text, HTML, JSON, etc.) of the content being sent in an HTTP response. It enables the browser to understand how to interpret and display the received content correctly.

Here’s an example of how it works:

Content-Type: text/html; charset=utf-8


This header specifies that the content being sent in the HTTP response is HTML and encoded in UTF-8 character encoding.

How does the Content-Type header protect websites?

The Content-Type header is used by web servers to indicate the type of data that is being sent to the client’s browser. The header also tells the browser how to interpret the data, whether it should be displayed as text, HTML, XML, JSON, or some other format.

Attackers can use cross-site scripting (XSS) by “lying” to the browser about the type of data, and then the browser interprets the response data incorrectly. For example, if the server sends an HTML page with a Content-Type of text/plain, the browser may not interpret the page as HTML, and any embedded scripts or tags may not be executed, or vice versa.

How to implement the Content-Type header

To implement the Content-Type header on Apache, you can use the AddType directive in your .htaccess or Apache configuration file:

AddType text/html .html


On Nginx, you can use the types directive in your server configuration file:

types {
text/html html;
application/json json;


This sets the Content-Type header for HTML files to text/html and for JSON files to application/json.

8. The Permissions-Policy header

This used to be known as ‘Feature-Policy’. It works by stopping added-on parts of your website (like advertisers and iframes) from gaining access to certain browser features like:

  • Geolocation
  • Fullscreen
  • Speaker
  • USB
  • Autoplay
  • Speaker
  • Microphone
  • Battery status

Permissions Policy allows the top-level site to define what it and its third parties intend to use — and removes the need for the user to understand if it’s allowed or not. For example, if the website runs advertisements, it may want to disable the microphone, camera and GPS to prevent unscrupulous advertisers from spying on the user. It’s mostly used for iframes.

As an example:

Chrome's Content Security Policy generator.
Chrome's Content Security Policy generator.

Note – if you are still using the Feature-Policy header, the Permissions-Policy will be given a higher priority.

The new Permissions Policy header uses “Structured Fields” which means that it standardises the use of certain fields and changes things slightly within the code. For example:

With Feature-Policy:


geolocation ‘self’ https://example.com; camera ‘none’


With Permissions-Policy:


geolocation=(self “https://example.com”), camera=()


How do Permissions-Policy headers protect websites?

If your site has any of the following features, then you might want to allow geolocation only for your site and the trusted site, but not for the advertising site.

  • Your site is https://www.website.com
  • Your site embeds an iframe from same-origin (https://www.website.com)
  • Your site embeds an iframe from https://trusted-site.com that you trust
  • Your site also displays ads served by https://adverts.com that you don’t trust

You can do this via the following:


Permissions-Policy: geolocation=(self “https://trusted-site.com”)


And explicitly set the allow attribute to the iframe tag for the trusted site:

<iframe src=”https://trusted-site.com” allow=”geolocation”>


You can find a lot more detailed information about this header on Chrome’s guidance page.

How to implement Permissions-Policy headers

In the example below, the brackets () with nothing inside sets the permissions for geolocation, microphone, camera, and payment to an empty value, indicating no permission is granted. You can also use ‘none’ for the same result. External sites you want to be allowed go inside the brackets, like this:

Header always set Permissions-Policy “geolocation=(self “https://trusted-site.com” “https://a-different-site.com”), microphone=(), camera=(), payment=()


And then if you leave the brackets empty, that disallows them:

Header always set Permissions-Policy “geolocation=(), microphone=(), camera=(), payment=()”


You can also specify ‘none’ rather than using brackets if you want:

Header always set Permissions-Policy “geolocation=(), microphone=(), camera=(), payment=(), fullscreen=’none'”


For Apache, this goes in either httpd.conf or apache2.conf depending on your server or here /etc/apache2/sites-enabled/webdock.conf:

Header always set Permissions-Policy “geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()”


Header always set Permissions-Policy “geolocation=()” which disables the geolocation feature.


For NGINX, all the Nginx configuration goes under http block in nginx.conf or any other custom file.

add_header Permissions-Policy “vibrate ‘none’;”;
which disables the vibrate feature


add_header Permissions-Policy “geolocation ‘none’; camera ‘none’; speaker ‘none’;”;
which disables the geolocation, camera and speaker


9. The X-Permitted-Cross-Domain-Policies header

The X-Permitted-Cross-Domain-Policies header is a security header that tells the browser which cross-domain policies are allowed. It helps protect websites from certain types of attacks, such as cross-site scripting and clickjacking.

How does this header protect websites?

An attacker could exploit a website that does not have this header set by trying to load resources from other domains and subdomains that the website trusts. This could allow the attacker to execute malicious scripts or steal sensitive information.

How to implement the X-Permitted-Cross-Domain-Policies header

There’s a few options here:

  • None – no policy is allowed
  • All – everything is allowed
  • Master-only – allow only the master policy
  • By-content-only – Allow only a certain type of content. Example – HTML
  • By-ftp-only – applicable only for an FTP server

In Apache, add to the httpd.conf file:


Header set X-Permitted-Cross-Domain-Policies “none”


For NGINX, add this under the Server block in nginx.conf:

add_header X-Permitted-Cross-Domain-Policies “none”;


This will ensure that no cross-domain policies are allowed, which is the most secure option. However, you can also set the header to allow certain policies, such as “master-only” or “by-content-type”.

Implementing your security headers

The most important thing is to back up your site before you start. Ideally, you also don’t want to be doing this on a live site — staging is best.

You will probably need your developer to help with this if you are not particularly tech-savvy. In case you need more assistance, here’s a helpful HTTP headers cheat sheet from the OWASP website.

How do you implement all security headers on Apache?

As before – backup your httpd.conf / .htaccess file and website before you start. Ensure that the mod_headers module is enabled in your Apache configuration (httpd.conf or an included file) before you start too.

You can check by looking for the line LoadModule headers_module modules/mod_headers.so and ensure it is not commented out (i.e., does not start with #), e.g:

# LoadModule headers_module modules/mod_headers.so

Also, be sure to test each header to ensure it doesn’t break any functionality on your site. You can add the following to the .htaccess file in Apache which sets the default:


<IfModule mod_headers.c>
# Content Security Policy (CSP)
Header always set Content-Security-Policy “default-src ‘self’;”

# X-Content-Type-Options
Header always set X-Content-Type-Options “nosniff”

# X-Frame-Options
Header always set X-Frame-Options “DENY”

# X-XSS-Protection
Header always set X-XSS-Protection “1; mode=block”

# Strict-Transport-Security (HSTS)
Header always set Strict-Transport-Security “max-age=31536000; includeSubDomains; preload”

# X-Permitted-Cross-Domain-Policies
Header always set X-Permitted-Cross-Domain-Policies “none”

# Referrer-Policy
Header always set Referrer-Policy “no-referrer”

# Content-Type
Header always set Content-Type “text/html; charset=UTF-8”

# Permissions-Policy
Header always set Permissions-Policy “geolocation=(), microphone=(), camera=(), payment=()”



After adding these directives to your httpd.conf file, you will need to restart Apache for the changes to take effect. Please note that modifying the httpd.conf file requires administrative access to the server.

How do you implement all security headers on NGINX?

For NGINX you could add the following in the nginx.conf file:


server {
# Other server configuration directives…

# Content Security Policy (CSP)
add_header Content-Security-Policy “default-src ‘self’;”;

# X-Content-Type-Options
add_header X-Content-Type-Options nosniff;

# X-Frame-Options
add_header X-Frame-Options “DENY”;

# X-XSS-Protection
add_header X-XSS-Protection “1; mode=block”;

# Strict-Transport-Security (HSTS)
add_header Strict-Transport-Security “max-age=31536000; includeSubDomains; preload”;

# Referrer-Policy
add_header Referrer-Policy same-origin;

# Permissions-Policy
add_header Permissions-Policy “geolocation=(), microphone=(), camera=(), payment=(), fullscreen=()”;

# X-Permitted-Cross-Domain-Policies
add_header X-Permitted-Cross-Domain-Policies none;

# Other server configuration directives…


Make sure to restart your server for the changes to take effect.

How do you implement security headers on a WordPress website?

You can use a plugin such as Redirection to add various security headers to your WordPress website. However, be sure to also have the FTP details on hand so that you can disable this plugin remotely if necessary, as adding security headers could potentially break your site. This is why it’s always better to test them on a staging site first.

To add headers via Redirection plugin, navigate to the Plugin and choose the HTTP headers option. You can now click the “Add Header” button and choose “Add Security Presets”.

It’s worth adding the headers one at a time and updating the site, so that you can test whether any of them break the site. In particular, Content Security Policy has a tendency to break WordPress sites as there are so many external scripts which need to load for plugins, themes etc.

How do you check security headers are implemented?

To check whether your HTTP security headers are implemented correctly, you can use a couple of popular tools:

1. https://securityheaders.com/
2. https://domsignal.com/secure-header-test

These will give you a visual indication of whether each header is implemented or not. You can also check the actual HTTP headers using a tool like Rex Swain’s HTTP Viewer.


The recommendations above are for informational purposes only and Sleeping Giant Media will not be responsible for any damages to websites caused by implementing security headers via the instructions above. You should check with your developer and do your own research into whether these security headers will be compatible with your website and applications before implementing them.

Stay on top of your technical SEO

Got all that? If you have any further questions about security headers, or even website best practices in general, our experienced team of SEO specialists are always on hand to point you in the right direction. For more expert digital marketing and website optimisation guidance, be sure to keep up with the latest on our blog.



Giant Wednesday

Sign Up For More

Stay up to date with the latest happenings, learnings, events & more with our GIANT Newsletters.

Contact Us

Top Floor, The Civic Centre, Castle Hill Avenue, Folkestone CT20 2QY.

 Show me directions

 01303 240715

 Send us a message

Copyright © 2022 Sleeping Giant Media. All Rights Reserved.