How to Secure Drupal HTTP Headers

How to Secure Drupal HTTP HeadersIn this blog post I will briefly overview some of the very useful HTTP response header parameters that will help to secure any website. HTTP Response headers are name-value pairs of strings sent back from a server with the content you requested. More information can be found on the internet.

I will cover some of the most important security-related HTTP parameters. The original blog post was written by Scott Helme who is the creator of This is a brief overview of his blog post to introduce this technique to our readers.

Most of the header parameters can be set either in your .htaccess file (Apache) or webserver configuration files (preferred).

It is always good to review your response HTTP headers and remove some of them (if the system allows). For instance PHP version or webserver version.

Important: Make sure to QA your website after making the changes to the HTTP headers. Headers such as X-Frame-Options and Access-Control-Allow-Origin may break your site if incorrectly configured.

Also as a result of this blog post I built Drupal 8 module. The module is similar to Security Kit Drupal 7 module.


This response header can be used to configure a user-agent's built in reflective XSS protection. Currently, only Microsoft's Internet Explorer, Google Chrome and Safari (WebKit) support this header.

Set this in Nginx:
add_header X-Xss-Protection "1; mode=block" always;

Set this in Apache:
Header always set X-Xss-Protection "1; mode=block"


The X-Powered-By header gives information on the technology that's supporting the Web Server. This parameter specifies the technology (e.g. PHP etc..) supporting the web application (version details are often in X-Runtime, X-Version, or X-AspNet-Version

To disable this parameter edit your php.ini file. Set expose_php = Off and restart your webserver.


This header parameter prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server. It reduces exposure to drive-by downloads and the risks of user uploaded content that, with clever naming, could be treated as a different content-type, like an executable.

Set this in Nginx:
add_header X-Content-Type-Options "nosniff" always;

Set this in Apache:
Header always set X-Content-Type-Options "nosniff"


Clickjacking protection. Valid values include DENY meaning your site can't be framed, SAMEORIGIN which allows you to frame your own site or ALLOW-FROM which lets you specify sites that are permitted to frame your own site.

Set this in Nginx:
add_header X-Frame-Options "SAMEORIGIN" always;

Set this in Apache:
Header always set X-Frame-Options "SAMEORIGIN"


Access-Control-Allow-Origin is apart of the Cross Origin Resource Sharing (CORS) specification. This header is used to determine which sites are allowed to access the resource by defining either a single origin or all sites (denoted by a wildcard value). It should be noted that if the resource has the wildcard value set, then the Access-Control-Allow-Credentials option will not be valid and the user-agent's cookies will not be sent in the request. Valid values are:

  • * - Wildcard value allowing any remote resource to access the content of the resource which returned the Access-Control-Allow-Origin header.
  • - A single serialized origin (http://[host], or https://[host]).

Content Security Policy

This HTTP header parameter allows you to define a whitelist of approved sources of content for your site. By restricting the assets that a browser can load for your site you will have extra level of protection from XSS attacks.

Set this in Nginx:
add_header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'" always;

Set this in Apache:
Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"

Read more Content Security Policy - An Introduction

HTTP Strict Transport Security

This policy will enforce TLS on your site and all subdomains for a year.

Set this in Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;

Set this in Apache:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Read more HSTS - The missing link in Transport Layer Security

Drupal modules

Download Drupal 8 module (github)

Useful links

  1. List of HTTP header fields
  2. Security HTTP Response Headers
  3. Security through HTTP response headers
  4. Hardening your HTTP response headers
  5. Introduction to HTTP Response Headers for Security
  6. Guidelines for Setting Security Headers