Skip to main content

Secure Headers (Helmet)

When the API responds to a request, it does not just send the body, it also sends a set of HTTP headers. A well-chosen set of security headers can close entire classes of vulnerabilities at the browser level, with no code changes elsewhere. The library that sets them is called Helmet.

This page walks through the headers Helmet sets in Dashify and what each one prevents.

The list

Helmet enables, by default, a curated set of headers. Each one is small. Together they harden the response significantly.

HeaderWhat it does
Strict-Transport-SecurityTells the browser "always use HTTPS for this site." Prevents protocol downgrade attacks.
X-Frame-OptionsForbids other sites from embedding this page in an iframe. Prevents clickjacking.
X-Content-Type-Options: nosniffForbids the browser from "sniffing" content types, it must use what the server says. Prevents MIME-confusion attacks.
Referrer-PolicyLimits how much of the URL is sent in the Referer header on outbound links. Prevents leaking sensitive query parameters.
Cross Origin-Embedder-PolicyPrevents embedding cross origin resources without explicit consent.
Cross Origin-Opener-PolicyIsolates the browsing context from cross origin windows.
Cross Origin-Resource-PolicyPrevents the response from being loaded by an unrelated origin.
X-DNS-Prefetch-ControlDisables the browser's DNS prefetch (a privacy improvement).
X-Download-OptionsPrevents IE from opening downloads in the site's context.
X-Permitted-Cross-Domain-PoliciesDisables Flash/Acrobat cross-domain access.
Content-Security-PolicyAlready covered in detail on the CSP page.

Why each one matters

HSTS, Strict-Transport-Security

Set as max-age=31536000; includeSubDomains; preload in production. This tells the browser:

  • "For the next year, never visit this domain over HTTP. Always use HTTPS."
  • "Apply the same rule to every subdomain."
  • "I want to be on the HSTS preload list" (a list browsers ship with so the rule applies even on the very first visit).

The attack HSTS prevents is protocol downgrade. A user types dashify.example.com (no protocol). The browser tries http://dashify.example.com. An attacker on the user's network intercepts and serves a fake page. With HSTS, the browser refuses to even attempt HTTP, the redirect never happens, the attack never lands.

X-Frame-Options, clickjacking

X-Frame-Options: DENY (or SAMEORIGIN) tells the browser: "do not render this page inside an iframe." Without this, an attacker could:

  1. Set up a fake page with a button that says "Win a prize."
  2. Embed Dashify in an invisible iframe positioned so the "Delete account" button is exactly where the prize button is.
  3. The user clicks the prize button. Their click actually lands on the Dashify "Delete account" button.

That is clickjacking. X-Frame-Options: DENY makes it impossible because the browser refuses to render Dashify in an iframe at all.

CSP's frame-ancestors 'none' does the same thing, more flexibly. Modern browsers honour both. Dashify sets both.

X-Content-Type-Options, MIME sniffing

When a server serves a file, the browser usually trusts the Content-Type header. Some browsers, historically, would override the server's choice if the file content "looked like" a different type, a phenomenon called MIME sniffing.

This was a vulnerability vector. An attacker could upload a file declared as text/plain that the browser would sniff as HTML and execute scripts in it. X-Content-Type-Options: nosniff tells the browser "trust the server, do not guess." The vulnerability is closed.

Referrer-Policy

When you click a link from page A to page B, the browser sends the URL of page A in the Referer header. If the URL contains a session id, an OAuth code, or a sensitive parameter, that information leaks to page B's server.

Referrer-Policy: strict-origin-when-cross origin (Helmet's default) limits the leak: same origin clicks send the full URL; cross origin clicks send only the origin (no path, no query). This is enough to identify "Dashify sent the user here" without exposing what they were doing.

Cross Origin-* headers

A relatively new family of headers that lets a page declare its isolation expectations. Used together they enable the browser to put the page in a more secure execution context (one that allows SharedArrayBuffer, for example). For Dashify they primarily serve a defensive purpose: they prevent the page from being embedded or its responses from being loaded in unexpected cross origin contexts.

The exact configuration is slightly conservative, Dashify uses Cross Origin-Resource-Policy: same origin for API responses (so they cannot be loaded by another site) and Cross Origin-Opener-Policy: same origin for pages.

Why headers, not in-application code

Setting these as response headers has three big advantages over enforcing the same rules in application code:

  • It scales for free. Every response gets the same protection without each route having to remember.
  • The browser does the work. The protections are enforced by the browser before the response is even rendered. There is no "race condition" between the page loading and the protection kicking in.
  • They compose with your application. Headers do not constrain how you build the app. They just narrow the attack surface around it.

Helmet in Dashify

Helmet is wired into the API's middleware stack as one of the very first middlewares, before routes, before parsing, before anything. Every response from every endpoint goes through it. There is no opt-out.

In development the policy is sometimes relaxed for tooling that needs cross origin embedding (Storybook, for instance). The relaxations are scoped to development, production runs with the strict configuration.

Verifying

You can verify any of these in the browser by opening the developer tools, looking at the Network tab, and inspecting the response headers on any API call. They should all be present.

A handy external check: securityheaders.com grades a deployment based on the headers it serves. Dashify aims for an A+ rating in production.

Key takeaways

  • Helmet sets a curated bundle of security-related HTTP response headers as middleware on every API response.
  • HSTS prevents HTTP downgrade attacks. X-Frame-Options prevents clickjacking. X-Content-Type-Options prevents MIME sniffing.
  • The Referrer-Policy prevents sensitive URL parameters from leaking via the Referer header.
  • The Cross Origin-* family isolates the page from unexpected cross origin contexts.
  • Headers are enforced by the browser, before the page renders, no race conditions.