How to check if a website uses HSTS and HSTS preload
Contents
2. How web browsers know that a site uses HSTS
3. The meaning of HTTP Strict Transport Security (HSTS) header directives
4. Strict Transport Security Preload (HSTS Preload)
5. How to check HSTS of a website
6. How to check HSTS preload of a website
6.1 How to check HSTS preload of a website in the GUI / online
6.2 How to check HSTS preload of a website in the command line
6.3 How to check HSTS preload of a website without third-party services
6.3.2 Using a list from the Chromium web browser's HSTS preload file
7. Online HSTS and HSTS Checking Services preload websites
8. Testing HSTS. How to remove HSTS settings for specific sites in a web browser
8.1 How to remove HSTS settings from Chromium / Google Chrome
8.2 How to remove HSTS settings from Firefox
8.3 How to create a Firefox profile for testing HSTS
8.4 How to test HSTS with cURL
8.5 How to test HSTS with wget
1. What is HTTP Strict Transport Security (HSTS) and what you need to know if you are going to enable HSTS
HSTS (short for HTTP Strict Transport Security) is a mechanism that forcibly activates a secure connection via the HTTPS protocol. This security policy allows you to immediately establish a secure connection instead of using the HTTP protocol. The mechanism uses a special Strict-Transport-Security header to force the browser to use the HTTPS protocol even when following links with an explicit indication of the HTTP protocol (http://). The mechanism was described in RFC6797 in November 2012.
HTTP Strict Transport Security (HSTS) is a policy mechanism that helps to protect websites against man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking.
Simply put, if a website uses HSTS, the web server will not connect to this site via HTTP regardless of other web server settings and redirects. This, by the way, has rather non-obvious consequences: if you want to switch a site using HSTS to HTTP (for example, you do not want to buy a certificate for the website or you want some pages not to use HTTPS), you will not be able to do this – web browsers that have already accessed your site on HTTPS will not connect to it via HTTP (at least until the header expires, which is usually set to 1 year).
2. How web browsers know that a site uses HSTS
There are 2 ways web browsers can know that a site uses HSTS:
1) The HTTP header of the web server informs that this website uses HSTS. An example of such a header:
strict-transport-security: max-age=31536000
After receiving such a header, the user's web browser remembers that this site uses HSTS and subsequently tries to connect to it only via the HTTPS protocol, prohibiting the use of HTTP.
As you might guess, the weak link here is the very first transmission of the header with the value “strict-transport-security”.
2) Lists that contain sites using HSTS. Such a list is maintained by Google and is supported by all web browsers. For more information, see the links:
- https://hstspreload.org/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
3. The meaning of HTTP Strict Transport Security (HSTS) header directives
Examples of HTTP Strict Transport Security (HSTS) headers:
strict-transport-security: max-age=31536000 strict-transport-security: max-age=63072000; includeSubDomains; preload
As you can see, the header starts with the string “strict-transport-security: “, followed by directives. Let's look at the meaning of these directives
max-age=EXPIRATION TIME
The time in seconds during which the browser should remember that access to the site is possible only via the HTTPS protocol. For example, the value 31536000 corresponds to one year. A value of 300 corresponds to 5 minutes.
includeSubDomains
An optional directive. If this optional parameter is specified, this rule also applies to all subdomains of the site.
preload
An optional and non-standard directive. Strict Transport Security preload. When using preload, the max-age directive must be at least 31536000 (1 year) and the includeSubDomains directive must be present. Not part of the specification.
4. Strict Transport Security Preload (HSTS Preload)
Google maintains the HSTS preload service. By following the guidelines and successfully submitting your domain, you can be sure that browsers will connect to your domain over only secure connections. Although the service is maintained by Google, all browsers use this preload list. However, it is not part of the HSTS specification and should not be considered official. See also:
- Information regarding the HSTS preload list in Chrome: https://www.chromium.org/hsts/
- Consultation of the Firefox HSTS preload list: nsSTSPreloadList.inc
Please note that HSTS Preload can include both individual domains (including all subdomains) and entire top-level domains (TLDs). For example, all sites in the .dev domain zone must have a valid SSL certificate, otherwise it will be impossible to connect to the site.
For sites with top-level domains included in HSTS Preload, you can also get free test certificates for 3 months (and use this scheme for years). For example, in my tests I got a free SSL certificate for the .dev domain without any problems when confirming domain ownership using a DNS record. In theory, there may be a problem confirming domain ownership if you use HTTP requests for confirmation. Although, it is possible that command line tools will ignore HSTS Preload and will still be able to confirm ownership using an HTTP request (for example, if you use a tool like acme-tiny) – I have not tested this.
Also see:
5. How to check HSTS of a website
Since the whole point of using HSTS is to pass the strict-transport-security header to the web browser, it is enough to check whether this header is present in the web server's response. This can be done with a command like:
curl -s -D- URL | grep -i -E '^strict'
For example:
curl -s -D- https://pattaya-pages.com/ | grep -i -E '^strict' curl -s -D- https://suip.biz/ | grep -i -E '^strict'
If the header is displayed, then HSTS is used. If nothing is displayed, then:
- HSTS is not used
- OR some other error, for example, could not connect to the server
An analogue of the previous command, which shows one of two phrases depending on whether HSTS is used:
url='https://hackware.ru'; r=`curl -s -D- $url | grep -i -E '^Strict'`; [ -n "$r" ] && echo -e "HTTP Strict Transport Security is enabled\n${r%$'\r'}" || echo 'HTTP Strict Transport Security is NOT enabled'
Please note that the URL must be specified as the value of the $url variable:
url='https://suip.biz'; r=`curl -s -D- $url | grep -i -E '^Strict'`; [ -n "$r" ] && echo -e "HTTP Strict Transport Security is enabled\n${r%$'\r'}" || echo 'HTTP Strict Transport Security is NOT enabled'
6. How to check HSTS preload of a website
6.1 How to check HSTS preload of a website in the GUI / online
You can go to the official website https://hstspreload.org and enter the domain you are interested in to check HSTS preload. There you can also add your site to HSTS preload or request to exclude it from HSTS preload (this may take a long time!).
6.2 How to check HSTS preload of a website in the command line
To check in the command line, you can use Puppeteer + the hstspreload.org website.
To do this, install the Puppeteer package (section “How to install Puppeteer”), create the hstspreload-status.js file and copy into it:
let puppeteer; try { puppeteer = require('/usr/lib/node_modules/puppeteer'); } catch (error) { try { puppeteer = require('/usr/local/lib/node_modules/puppeteer'); } catch (error) { try { puppeteer = require('puppeteer'); } catch (error) { console.log('Please install "puppeteer" package'); } } } function delay(time) { return new Promise(function(resolve) { setTimeout(resolve, time) }); } async function run() { if (puppeteer == null) return; const url = 'https://hstspreload.org/?domain=' + process.argv[2]; const browser = await puppeteer.launch(); const page = await browser.newPage(); const customUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'; await page.setViewport({width: 1440, height: 3440}); await page.setUserAgent(customUserAgent); await page.goto(url); await page.waitForSelector('#status'); await delay(5000); const tag = await page.$eval('#status', el => el.innerText) console.log(tag); browser.close(); } run();
Run the check with the following command, where instead of DOMAIN specify the site you are interested in:
node hstspreload-status DOMAIN
For example:
node hstspreload-status hackware.ru node hstspreload-status paypal.com node hstspreload-status www.paypal.com node hstspreload-status youtube.com
Top-level domains (TLD) can also be checked this way:
node hstspreload-status com node hstspreload-status dev node hstspreload-status microsoft
6.3 How to check HSTS preload of a website without third-party services
6.3.1 hstspreload
Since HSTS preload is in the source code of the Chromium web browser, and the source code of this web browser is open, you can check domains for presence in HSTS preload using this file.
You can use various alternatives, I got lucky with hstspreload.
hstspreload is a Chromium HSTS Preload list as a Python package.
The package provides one function: in_hsts_preload(), which takes an IDNA-encoded host and returns True or False as to whether the host should only be accessed via HTTPS.
This package is entirely built using an automated script that runs once a month. That is, the data in this package is updated once a month.
The file used as a data source (Base64 encoded file): https://chromium.googlesource.com/chromium/src/+/main/net/http/transport_security_state_static.json?format=TEXT
For information on how to install hstspreload, see https://en.kali.tools/?p=1933 (section “How to install hstspreload”).
Create a file hstspreload_checker.py and copy the following content into it:
from sys import argv import hstspreload host = argv[1] print (hstspreload.in_hsts_preload(host))
Run the file as follows:
python hstspreload_checker.py DOMAIN
For example, the following command will check if the domain suip.biz is in the HSTS preload list:
python hstspreload_checker.py suip.biz
More examples of checking:
python hstspreload_checker.py hackware.ru python hstspreload_checker.py youtube.com python hstspreload_checker.py paypal.com python hstspreload_checker.py www.paypal.com
You can also check top-level domains (TLD):
python hstspreload_checker.py com python hstspreload_checker.py net python hstspreload_checker.py dev python hstspreload_checker.py microsoft python hstspreload_checker.py youtube
If a top-level domain is added to the HSTS preload list, then all second-level and any subdomains will also be accessible via only HTTPS:
python hstspreload_checker.py just.whatever.if.dev
6.3.2 Using a list from the Chromium web browser's HSTS preload file
Having already figured out hstspreload, I thought, why do we need an intermediary? You can download the HSTS preload list file like this (you only need to do it once):
curl 'https://chromium.googlesource.com/chromium/src/+/main/net/http/transport_security_state_static.json?format=TEXT' > transport_security_state_static.txt cat transport_security_state_static.txt | base64 -d > hstspreload.txt
You can then search by domains like this:
grep '"DOMAIN"' hstspreload.txt
For example:
grep '"youtube.com"' hstspreload.txt
Found:
{ "name": "youtube.com", "policy": "google", "mode": "force-https", "include_subdomains": true },
Note that there are single quotes first and then double quotes – this achieves an exact match search. If you want to search by part of the name, then you do not need to use quotation marks, for example:
grep youtube.com hstspreload.txt
Found:
{ "name": "withyoutube.com", "policy": "google", "mode": "force-https", "include_subdomains": true }, { "name": "youtube.com", "policy": "google", "mode": "force-https", "include_subdomains": true },
This method allows you to search for top-level domains, but in this case they need to be placed in quotation marks, as shown above, for example:
grep '"dev"' hstspreload.txt
Will be found:
{ "name": "dev", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
7. Online HSTS and HSTS Checking Services preload websites
If you don't want to install any tools, you can check for the presence of the strict-transport-security header and whether the site is included in the HSTS preload list using the following service (you need to enter the address of the web page to check):
This service will display the result of the check, as well as the strict-transport-security header with all its valuesfor the website being checked.
If you want to check a top-level domain for inclusion in the HSTS preload list, then the following service is ideal for you:
8. Testing HSTS. How to remove HSTS settings for specific sites in a web browser
If you are a developer or webmaster and you are testing HSTS on localhost or another domain in a development environment, then you need to be more careful with HSTS, since these settings get stuck in web browsers tightly.
You may find yourself in the following interesting situation:
- Your localhost sends an HSTS header to your web browser
- The web browser refuses to connect to localhost (or another domain in the development environment) via HTTP after receiving the HSTS header
- … Actually, this is the end, because until recently, Google Chrome did not have a convenient way to remove the HSTS setting for a specific site, and Firefox does not have a working way to remove HSTS entries at all
As a result, you find yourself in an awkward situation where you can only contact localhost from your web browser via HTTPS…
8.1 How to remove HSTS settings from Chromium / Google Chrome
In the address bar of your web browser, enter:
chrome://net-internals/#hsts
In the “Query HSTS/PKP domain” field, you can check whether HSTS is applied for the domain.
If HSTS is applied for the domain, many lines will be displayed. The lines seem to be duplicated. All lines are divided into two groups:
- those that start with “static” – if the value of these lines is not empty, then the domain uses HSTS preload
- those that start with “dynamic” – if the value of these lines is not empty, then the domain uses HSTS according to the strict-transport-security header
Found: ………………………. ………………………. ………………………. static_sts_domain: static_upgrade_mode: UNKNOWN static_sts_include_subdomains: static_sts_observed: static_pkp_domain: static_pkp_include_subdomains: static_pkp_observed: static_spki_hashes: dynamic_sts_domain: hackware.ru dynamic_upgrade_mode: FORCE_HTTPS dynamic_sts_include_subdomains: false dynamic_sts_observed: 1735963517.717188 dynamic_sts_expiry: 1767499517.717185
You can NOT delete a site if it is placed in HSTS preload. To delete other sites, enter the domain name in the “Delete domain security policies” field and click the “Delete” button.
To verify that the domain data has been removed, re-run the query in “Query HSTS/PKP domain”.
8.2 How to remove HSTS settings from Firefox
You can find a couple of methods on the Internet to remove HSTS from Firefox, but they do not work at the time of writing.
I have not tried this method, but if you have nothing to lose, then send a strict-transport-security header from the domain you want to exclude from HSTS with the max-age directive set to a very small value, for example:
strict-transport-security: max-age=3
This header may be able to overwrite the stored HSTS value.
By the way, for testing purposes, set a small value for the max-age directive – as a result, the web browser itself will clear the HSTS value of the tested domain after the specified time.
As a last resort, you can change the Firefox profile.
8.3 How to create a Firefox profile for testing HSTS
To avoid getting into trouble with Firefox when testing HSTS, you can create a special profile.
To do this, create a new profile using the following command:
firefox --ProfileManager
Then launch Firefox using the following command (replace PROFILE with the name of the profile you created in the previous command):
firefox -P PROFILE
For example:
firefox -P TestHSTS
You can use any profile name for this, just do not use the “default” profile, otherwise there is no point.
8.4 How to test HSTS with cURL
If all you want to do is check whether the HSTS header is set up correctly and whether web browsers and other web clients respond to it correctly, then command line utilities are quite suitable for this. For example, curl:
curl --hsts hsts.txt https://hackware.ru curl --hsts hsts.txt https://youtube.com
As a result of the previous command, if HSTS is enabled for the specified site, then the corresponding value will be saved to the hsts.txt file, including the HSTS expiration date, for example:
# Your HSTS cache. https://curl.se/docs/hsts.html # This file was generated by libcurl! Edit at your own risk. hackware.ru "20260104 04:04:52" .youtube.com "20260104 04:04:55"
8.5 How to test HSTS with wget
Similarly, you can test HSTS with wget. The only difference is that wget already saves HSTS records to the file ~/.wget-hsts. You can analyze this file, or use a separate file for tests:
wget --hsts-file hsts.txt https://suay.site wget --hsts-file hsts.txt https://youtube.com
Example of hsts.txt contents:
# HSTS 1.0 Known Hosts database for GNU Wget. # Edit at your own risk. # <hostname> <port> <incl. subdomains> <created> <max-age> www.youtube.com 0 0 1735963445 31536000 youtube.com 0 1 1735963445 31536000 suay.site 0 0 1735963403 31536000
Related articles:
- Revealing the perimeter (CASE) (65.3%)
- TLS fingerprinting: methods for identifying client and server software (58.6%)
- TLS fingerprinting of clients: hash types, utilities for displaying TLS fingerprints of clients (58.6%)
- TLS fingerprinting of servers: hash types, utilities for displaying TLS fingerprints of servers (58.6%)
- How to see locked HTML code, how to bypass social content lockers and other website info gathering countermeasures (56.7%)
- How to save all information from Facebook profiles (RANDOM - 50%)