Helmet and Express.js

Helmet is a popular middleware for Express.js that conveniently makes your web app more secure. Specifically, it sets various HTTP headers to account for known security vulnerabilities with HTTP. While most developers simply bind their express instance (app.use(helmet())) and let Helmet take care of the rest , it's useful to understand what exactly Helmet does to protect your app. In this article, we discuss the 11 different middleware functions that Helmet uses to set your HTTP headers and make your requests more secure.

The Helmet Collection

Helmet is really a collection of 11 smaller middleware functions. These functions each set HTTP headers to address different vulnerabilities. Not all functions are included by default but we've listed all 11 and their purpose below. We've also flagged the ones that are included by default with Helmet for your convenience.

contentSecurityPolicy

This sets the Content-Security-Policy header which effectively creates a whitelist of all the places your browser can load resources from. This prevents things like Cross-site scripting (XSS) where attackers inject client-side scripts into web pages viewed by other users.

A good example of this would be a search engine. Let's say you have an engine that displays the search term on the results page. If an attacker writes up a malicious script and enters that as a search term, the result page may execute the script if the input isn't sanitized. By setting the Content-Security-Policy header, the browser blocks any resources / scripts not specified.

dnsPrefetchControl (default)

This middleware sets the browser's X-DNS-Prefetch-Control header. This prevents your browser from prefetching the IP address of any URL you may visit. While this improves performance, by disabling the browser's ability to prefetch IP's you ensure the client doesn't appear to be visiting things they aren't actually visiting.

frameguard (default)

This sets the X-Frame-Options header and prevents clickjacking attacks. Clickjacking is a technique used by hackers to make victims click on things via hidden iFrames. While a victim may think they are clicking on a link for a sale, etc., they actually click on a hidden iFrame link which triggers malicious action.

By setting the X-Frame-Options header, you effectively prevent the browser from loading malicious/hidden iFrames.

hidePoweredBy (default)

This removes the X-Powered-By header which reveals what is powering your app. If an attacker knows your using Node/Express, then they are one step closer to compromising your site. By removing the X-Powered-By header, you are giving attackers less information to work with.

hpkp

This sets the Public-Key-Pins header to prevent man-in-the-middle attacks. In a man-in-the-middle-attack, a hacker will interfere with the SSL handshake process and pose as a trusted site. You may think you are communicating over a secure connection but the attacker is really intercepting your messages and sensitive data.

By setting the Public-Key-Pins header, you effectively pin your public key so visitors can constantly compare your public key with the one they stored, preventing man-in-the-middle attacks.

hsts (default)

This sets the Strict-Transport-Security header. This really just forces HTTPS and never allows someone to visit the HTTP (unsecured) version of your app.

ieNoOpen (default)

This sets the X-Download-Options header. Specifically targeting older versions of Internet Explorer, this header prevents older browsers from letting you download and open HTML files in the context of your site.

This is important because if downloaded HTML can run in the context of the browser then malicious code can potentially run within the markup.

noCache

This sets several headers, including Cache-Control, Surrogate-Control, Pragma, Expires. This simply prevents cached versions of static assets from hanging around when you update your site.

While this isn't a direct vulnerability, it prevents clients from accessing outdated and potentially vulnerable versions of your assets.

noSniff (default)

This sets the X-Content-Type-Options header to 'nosniff' which prevents the browser from trying to guess the MIME type. When a browser guesses at the MIME type of a resource, it can unintentionally run malicious content by guessing incorrectly. This gives attackers the opportunity to trick or mislead clients into opening malicious files/scripts.

referrerPolicy

This sets the Referrer-Policy header so attackers can't see where you are coming from. If the header is set by a web browser, attackers can see the URL you came from, giving them more information to carry out malicious activity.

xssFilter (default)

This sets the X-XSS-Protection to prevent cross-site scripting attacks (XSS). Through cross-site scripting, seasoned attackers can essentially take control of the JavaScript running in your browser. This leaves the attacker with a wide open playground for manipulating your browser and stealing sensitive user input, etc.

Conclusion

This article only touches on some of the vulnerabilities faced with HTTP. While it's true that Helmet will automatically configure HTTP headers to prevent most well-known attacks, understanding the different middleware functions will help you understand what to watch out for when using Express.js.

Your thoughts?