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:
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:
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:
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.