Why does Google Chrome automatically redirect `http://app` to `https://app` but doesn't do that to `http://app2` or `http://napp`?
by yaobin.wen
Days ago, when I was working on the work project, I wanted to put an entry 127.0.0.1 app
in /etc/hosts
in order to open http://app
in the browser instead of using the IP address 127.0.0.1
. When I did this, I was surprised that Google Chrome would automatically redirect http://app
to https://app
.
After searching for the possible reasons for a while, eventually, I asked the question Why does Google Chrome automatically redirect http://app
to https://app
but doesn’t do that to http://app2
or http://napp
? on Stack Overflow. Because nobody answered the question after a few days, I forwarded the question to the chromium-discuss email group.
Under that email thread, another user replied me saying I could check the redirection activities in the “Network” tab in Chrome’s “Developer tools”. I did that. After I entered http://app
, I found one of the lines said “Status: 307” which means an internal redirect. When I clicked on that line, another tab was open for me to examine the details. In the Headers
tab, a line told the reason: “Non-Authoritative-Reason: HSTS”.
Google brought me to this answer which mentions the HSTS Preload List, which says:
This form is used to submit domains for inclusion in Chrome’s HTTP Strict Transport Security (HSTS) preload list. This is a list of sites that are hardcoded into Chrome as being HTTPS only.
So I entered app
and found its status is “app is currently preloaded”. But app2
and napp
were “not preloaded”. This is why Google Chrome automatically redirects http://app
to https://app
but doesn’t do that to http://app2
or http://napp
.
Some further search brought me to the page HTTP Strict Transport Security on The Chromium Projects. This page also provides the link to the .json
file that stores all the hardcoded addresses.
Because the original file is very large, about 17MB as of 2022-02-18, I put a compressed copy here for easier reference in the future.
At the beginning of transport_security_state_static.json
, I found the following lines:
...
// gTLDs and eTLDs are welcome to preload if they are interested.
{ "name": "android", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "app", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
...
So the gTLD (generic top-level domain) app
is forced to get redirected to its HTTPS
counterpart. This is what the article Introducing .app, a more secure home for apps on the web talks about.
But if app
is an gTLD, the domain names such as foo.app
should be impacted, but why is http://app
also redirected? In fact, this is an intentional behavior as discussed in Issue 794202: Should HSTS Preload List affect unqualified hostnames?:
I feel this is working as Intended. Such intranet sites are themselves broken by virtue of ICANN’s policies around delegating them in the first place. We also have in place the ICANN transition to warn users, particularly for cases like http://foo.dev
Unqualified hostnames should never be able to opt-in to HSTS. As a result of ICANN’s policy decisions, unqualified hostnames are effectively ‘squatters’, and should be considered deprecated and, as captured in SSAC policy, a security risk.
A follow-up comment says “to avoid confusion, when writing HSTS names I write, say, (*.)dev
and (*.)app
in order to try and convey exactly what is covered”.
But surely not everyone is happy about the reinforcement. In this article, the author hated the feature so much that he/she figured out the way to patch the DLL to disable this redirection feature: it’s nice to learn how to hack the browser, but it’s definitely insecure to work around the feature. Anyway, HSTS is reinforced for a reason.
Last but not least, Chrome’s built-in address to configure HSTS is chrome://net-internals/#hsts
.