Skip to main content

HTTP Security Headers in Drupal, Part 3: X Marks the Spot


This is the third article in a four-part series about HTTP security headers and Drupal: what they are, why you should care, and how to implement them to increase the security of your Drupal site. In this entry, I will be covering how to implement the Strict Transport Security, X Content Type Options, and X Frame Options headers. I’ll be relying on the groundwork laid out in Part 1, so if you haven’t read that yet, there’s a link to it below.

Strict Transport Security

HTTP Strict Transport Security (HSTS) strengthens your implementation of SSL/TLS by getting the User Agent to enforce the use of HTTPS. It forces a user's browser to connect to your site via HTTPS and converts any HTTP links to HTTPS before sending a response.

The Security Kit module provides an easy way to implement this header. Under the SSL/TLS dropdown on the module configuration page will be a toggle and options for this header. Toggle it on to enable. The Max-Age setting sets how long (in seconds) the browser’s user agent will cache the header before fetching it again on the next request. If your site contains subdomains, toggle the Include Subdomains option as well.

The Drupal Seckit strict transport security settings


X Content Type Options

X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. The only valid value for this header is nosniff.

For a Drupal 8, 9, or 10 site, you don’t have to do anything! It’s already set in Drupal core in core/assets/scaffold/files/.htaccess

In Drupal 7 X Content Type Options can be implemented via a hook_page_build() function in a custom module:

 * Implements hook_page_build().
function YOURMODULE_page_build(&$page) {
  // Set x-content-type-options header
  drupal_add_http_header('X-Content-Type-Options', 'nosniff');

X Frame Options

X-Frame-Options tells the browser whether you want to allow your site to be framed (loaded in an iframe element) or not. By preventing other sites from framing your site you can defend against attacks like clickjacking.

As with Strict Transport Security, the seckit module has us covered. In the module configuration under the Clickjacking dropdown, you will find settings for this header.

This header has 4 options, choose which strategy fits your use case, set it, save it, and forget it:

  • SAMEORIGIN is the default which allows you to frame your own site but denies all others from framing your site.
  • DENY completely disallows any site from framing your site.
  • ALLOW-FROM allows you to whitelist/specify which domains are allowed to frame your site, all others not on the list are denied.
Drupal Seckit x-frame-options header settings


That wraps it up for the third part of our HTTP security header series. In the final article, I’ll be covering how to implement the trickiest (and possibly most impactful) of the bunch: Content Security Policy.