Published:

What is HSTS?

HSTS stands for HTTP Strict Transport Security. Once a web browser is aware that a site uses HSTS, it will only access the site via HTTPS.

How does HSTS work?

When a user enters an URL such as example.com (mind the lack of http:// or https://) into the address bar, the browser defaults to contact the server via HTTP (not HTTPS). If the site is configured to use HSTS, the server responds with the Strict-Transport-Security header to inform the browser that the site wishes only to be visited via HTTPS. From then on, this browser will use HTTPS for any subsequent visits of example.com.

The Strict-Transport-Security header

The Strict-Transport-Security header is at the heart of HSTS. It is specified in the standard's RFC. The header consists of multiple directives. One of those directives is max-age. It tells the browser how long it should remember to access this website only via HTTPS.

The preload directive

The preload directive isn't part of the RFC. However, if the Strict-Transport-Security header includes the preload directive, it tells browser vendors that it wishes to be included in the so-called preload list. Webmasters can also submit their sites at https://hstspreload.org/.

The preload list is a list of domains compiled into browsers. If the example.com domain is on that list, the browser will access the site via HTTPS from the beginning. That means if the user enters example.com into the browsers address bar for the first time, the browser will recognize example.com as part of the preload list, and as a result, it will use HTTPS instead of HTTP for the first request.

Domains on the preload list

Top-level domains such as the .dev are on the preload list by default. This has a few consequences. First, a .dev domain must work with HTTPS. If not, it won't be accessible. Second, you don't have to specify the Strict-Transport-Security header.

For more details see .dev.

Configuring HSTS in Nginx

See HTTP Strict Transport Security (HSTS) and NGINX.

Example: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

Published by Robert Möstl

« Back to Blog