/jul 24, 2018

Fasten Your Helmet.js (Part 1): Securing Your Express HTTP Headers

By Bipin Mistry

Helmet.js is a useful Node.js module that helps you secure HTTP headers returned by your Express apps. HTTP headers are an important part of the HTTP protocol, but are generally transparent from the end-user perspective. The headers provide important metadata about the HTTP request or response so the client (browser) and server can send additional information in a transaction.

Why Secure HTTP headers?

Since users do not see HTTP headers, developers have a tendency to ignore them. However, HTTP headers can leak sensitive information about your app inadvertently, so it’s important to configure and use them in a secure way.

A popular way Express apps leak information is through the X-Powered-By header. This header informs the browser which server vendor and version you’re using. By default, Express exposes the X-Powered-By header and leaks “Express” (usually without a version number). Hackers typically cross-reference this information with a list of publicly disclosed known vulnerabilities, which makes your app a prime target for easy exploits -- especially if you’re running an unpatched version of Express.

What is Helmet.js?

Fortunately, Helmet.js makes securing HTTP headers easy for Node.js developers. Helmet.js is a collection of 12 Node modules that interface with Express. Each module provides configuration options for securing different HTTP headers. Here’s a list of the Node modules that are included with Helmet.js:

HTTP Header Helmet.js Default? Related Node Module
Content-Security-Policy   contentSecurityPolicy for setting Content Security Policy
Expect-CT   expectCt for handling Certificate Transparency
X-DNS-Prefetch-Control X dnsPrefetchControl://helmetjs.github.io/docs/dns-prefetch-control) controls browser DNS prefetching
X-Frame-Options X frameguard to prevent clickjacking
X-Powered-By X hidePoweredBy to remove the X-Powered-By header
Public-Key-Pins   hpkp for HTTP Public Key Pinning
Strict-Transport-Security X hsts for HTTP Strict Transport Security
X-Download-Options X ieNoOpen sets X-Download-Options for IE8+
Cache-Control   noCache to disable client-side caching
X-Content-Type-Options X noSniff to keep clients from sniffing the MIME type
Referrer-Policy   referrerPolicyto hide the Referer header
X-XSS-Protection X xssFilter adds some small XSS protections

Sourced from: https://github.com/helmetjs/helmet

For some HTTP headers, Helmet.js automatically defaults to the “secure” option. Others, like Content-Security-Policy, require the developer to make an explicit configuration. This is usually because the "best practice" may break functionality or degrade user experience -- so configurations must be tuned accordingly.

Helmet.js’s Github page does a great job providing an overview of each HTTP header, the attack scenario, and different Helmet.js configurations you can use. We won't go into the specifics of each header in this post; instead, we’ll focus on three areas:

  • How to inspect your HTTP headers
  • How to install Helmet
  • An example configuration: Content-Security-Policy

Next, click on the “Network” tab and select an HTTP request made by the browser. Since I am testing on my local machine, I’ve clicked ‘localhost’.

Chances are your Express application isn’t using Helmet.js or securely configuring HTTP headers, so you may see something like this:

Getting Started

How to Inspect Your HTTP Headers

First, you should become comfortable inspecting HTTP traffic generated by your app. All modern browsers have a “Developer Tool” feature that lets you inspect network traffic requested by the browser. In this example, we’ll use Chrome. You can find Developer Tools from the Chrome menu: Blog How to inspect with Chrome Developer tools

Next, click on the “Network” tab and select an HTTP request made by the browser. Since I am testing on my local machine, I’ve clicked ‘localhost’.

Chances are your Express application isn’t using Helmet.js or securely configuring HTTP headers, so you may see something like this:

Blog Response Headers without Helmet

You’ll notice that none of the security headers listed in the table above appear in the image. In fact, we are leaking our use of Express! Fortunately, this is a quick fix with Helmet.js.

How to Install Helmet.js

First, use npm to download Helmet.js (we’re assuming you already have Express installed):

npm install helmet --save

Then, include it in your app:

var express = require('express');
var app = express();
var helmet = require('helmet');

app.use(helmet());

Helmet will now implement it’s default HTTP header configurations when you start your Express app! You should see the HTTP response headers look something like this:

Blog Response Headers with Helmet

Notice how Helmet.js disables the X-Powered-By header? Pretty cool :)

Want a demo of Veracode Interactive Analysis?

Veracode Interactive Analysis (IAST) helps teams instantly discover vulnerabilities in their applications at runtime by embedding security into their development processes and integrating directly into their CI/CD pipelines. Get a demo.

Related Posts

By Bipin Mistry

Bipin Mistry is Sr. Director of Product Management for WAS/IAST product line.  Prior to joining Veracode he was VP Product Management for NEC/Netcracker in their SDN/NFV and Security business unit.  At NEC/Netcracker Bipin’s primary focus is to develop solutions and architectures specifically mapped to NFV/SDN and Orchestration. He has over 28 years expertise in Security, Software Architectures, Mobile and Core Networking Technologies, Product Management, Marketing, Engineering and Sales.  Prior to joining NEC/Netcracker Bipin was VP President of Product Management for a security startup in the field of DDoS analysis and mitigation.  Bipin has also held architectural and management roles at both Juniper Networks (Chief Mobile Architect) and Cisco Systems (Sr. Director of SP Architecture).

Bipin lives Shrewsbury MA with his wife and 2 children.  In his spare time Bipin is a keen runner and is currently attempting to learn Spanish.