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;