The HTTP page at my website sends an HSTS header. This has no effect over HTTP, and should be removed. But what if i decide to not remove the error and preload my website through the HSTS Preload form? What happens?
Don’t think there’s any preload requirement over this so still should be able to preload.
However if you can’t follow the spec on how to use HSTS, and can’t figure out how to prevent this being illegitimately sent over HTTP (which could have been researched in the time it took to raise your question), then I’d really question whether you are ready for the commitment that preload binds you to. There are real dangers when preloading without understanding the full implications as it’s basically irreversible.
Related
In MDN HTTP Strict Transport Security (HSTS), it has an example of HSTS settings as below
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
where I can find the corresponding mean of max-age and includeSubDomains in RFC 6979, but it does not have the meaning of preload.
I have tested in latest Chrome and Firefox, and it seems that preload does not do anything at all. With and without preload, on requesting http request, both trials if using Chrome, can find 307 Internal Redirect made by Chrome browser without requesting to the server, which is what HSTS expect.
So what is the purpose of preload?
In addition, even if I add HSTS header, it will still have a chance to be attacked, on the first time the user visit the website with HTTP. How can we mitigate from this risk? That is, how can we tell the browser to add the domain to HSTS list before any request are sent to the server?
P.S.
I have found https://hstspreload.org/, which if I need to register the domain, requires me to add max-age and preload directive. Is it the reason why preload is necessary? And this should be the page where I should add my domain to ensure new user are safe from SSL Stripping Attack?
Preload is a big commitment. It will effectively be hardcoded into a browser’s code. Given it takes several months at a minimum to roll out new version, it’s basically irreversible.
Also as it’s down at the domain level, mistakes have been made. For example preloading domain.com but covering that blog.domain.com, or intranet.domain.com have not been upgraded to HTTPS. At this point your options are 1) upgrade side to HTTPS and live with zero users to the site until the or 2) reverse the preload and wait the months for that to roll out to all browsers and deal with zero users until then.
HTTPS is much more common now, so the risks are reduced but when HSTS preload first came out, these were real risks.
Therefore the preload attribute was a signal that the site owner was ready for that commitment. It also prevent someone else submitting a site that wasn’t using this header (whether maliciously or with good, but misguided, intentions).
You are correct in that it doesn’t “do” anything in the browser.
There was also talk of checking if the preload header was still being sent, and if not removing the preload but not sure if that’s done.
In trying to understand the HSTS mechanism, I could not wrap my head around the max-age directive. Couldn't the presence/absence of the HSTS header be enough to tell the browser to switch to HTTP or HTTPS ?
Browsers could remember "forever" a site should be contacted through HTTPS upon first contact, until the header dissapears in a later response. Plus the preload directive is there to support browsers too.
I could not find anything in the specs explaining this. https://datatracker.ietf.org/doc/html/rfc6797
I feel like I'm missing something like a specific scenario. This is not a critic, I'd like to understand why this directive is necessary.
It allows it to be rolled out gradually. It is recommended to set it with a very small max-age first and then grow it if there are no issues. This avoids a real risk of DoS-ing yourself for any non-HTTPS sites. While that is becoming rarer, when this first came out that was a real risk as HTTP was still very much the norm.
Say for example you deployed it on https://www.example.com and that web server also responds to (and sets the HSTS header on) https://example.com. Now let’s say you haven’t set up HTTPS on http://blog.example.com (it’s an unimportant static only domain) or on http://intranet.example.com (it’s not Internet-facing). Without a max-age you potentially just blocked those sites forever until you can deploy HTTPS to them (which can be trickier than just adding a bit of server config).
And without being able to visit the site the browser also couldn’t see the header had since been removed for the reset you suggest. Plus there’s also the fact that not every resource needs to set the HSTS header - just one is sufficient (though best practice is to set it on every HTTPS resource and including redirects), so the absence of the header is not sufficient to reset it. You explicitly need to set max-age=0.
Of course, nowadays, the recommended approach is HTTPS on all subdomains (and this is pretty much becoming the norm as the public Internet is much more HTTPS now than it was - though still not yet the default) and also on intranet sites (though difficult to be sure if that latter really is the norm across companies large and small).
You are right and this could have been implemented by having max-age as optional (instead of mandatory as it is now) and site owners could remove it from the HSTS header, once ready to roll it out fully, but having a default max-age of infinity is pretty dangerous - for the same reasons as given above. Having no defaults and making the implementor think about it, hopefully, makes them consider the appropriate one, or at very least makes them realise the commitment they are making it.
Preloading is the way to make it permanent, at which point the max-age attribute is redundant for those user agent’s implementing preload lists (primarily the most popular browsers).
There is the argument that nothing is permanent in this world - domains come and go and are taken on by new parties who may or may not want to use HTTPS (at least initially) - though as I say with HTTPS becoming the norm that’s less of an issue.
Also clogging up browser cache with an infinite policy just cause they visited your website once, years ago, seems kinda rude. Though browsers could cap it (which they do - more on which later) but better to be explicit for the value you want.
Both of the above reasons btw, are reasons I don’t particularly like preloading HSTS either.
It’s also worth noting that browsers often implement a cap on the max-age (usually because it is stored as a 32-bit integer for example) so sticking an arbitrarily large value in there is not going to do what you think it will. In fact I recall discussion that one browser (Firefox?) didn’t do bounds checking so setting a value larger than that actually possible overflowed and so prevented the policy being set at all! As I said previously, preload is the way to go to make it permanent.
A max-age of six months or one year is the recommended best practice and after this there are diminishing returns in terms of security of a larger policy anyway. If a visitor is not visiting your site every 6-12 months (at which point they will refresh the HSTS policy for another max-age seconds) then chances are they’re on a new browser or device anyway.
I know nothing about this stuff so please ELI5 in your replies.
Following the instructions from my provider, Dreamhost, I installed an SSL certificate and then added these lines to my .htaccess file to force HTTP requests to be rewritten to HTTPS requests.
# Redirect http requests to https
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Everything seems to be working correctly, ie: every time I try to access a page under that domain with HTTP, it is rewritten to HTTPS and the "Secure" icon shows in the address bar.
My question is, do I need to also enable HSTS? Reading about it, it seems to do the exact same thing as the previous changes to the .htaccess file. Here's an excerpt from A2 Hosting (not my provider):
Enabling HSTS
When HSTS is enabled for a site, web browsers automatically change any
insecure requests (http://) to secure requests (https://). All you
need to do to enable HSTS is add a header to your site's .htaccess
file. Web browsers recognize this header, and then take care of the
rest without any further intervention on your part.
They suggest adding this to .htaccess:
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Another tutorial, this time specific to Dreamhost, says to enable HSTS along with forcing HTTPS in the .htaccess file, but doesn't really say why. This page suggests something slightly different:
Header set Strict-Transport-Security "max-age=31415926; includeSubDomains; preload" env=HTTPS
Do I need the "https rewrite" code snippet AND HSTS? Or is having only the "https rewrite" code snippet good enough? Do I need the HSTS code at all, and if so, what's the difference between the two lines of HSTS code in my post?
HSTS lets the browser know to only connect over https by default but each one of the different flags does something a bit different:
includeSubdomains
That means that if your site is on mydomain.com, the policy will apply to all subdomains (i.e. foo.mydomain.com, bar.mydomain.com, etc). Without this included. the policy only applies for the exact domain in question.
preload
While HSTS is great conceptually, the first time someone types mydomain.com the browser will try to contact your site on http scheme since it doesn't know that you have your site on https which gives a MITM attacker room to serve you malicious version of the site (aka TOFU problem).
To work around this, there is a centralized list for browsers for sites that should be contacted on https by default but to be able to get yourself on that list, you have to have the preload flag in that header. You can see more about this here.
The default, if a scheme (http or https) is not explicitly specified, is http.
Therefore a redirect is necessary to redirect it to your preferred https version since most visitors who type the URL will not include the scheme and so go to http version.
HTTP Strict-Transport-Security (HSTS) is a security method, to ensure you always stay on https. It is not really intended to do away with the need for the redirect. In particular HSTS works by sending your web browser a message (using a HTTP response header) to say "please only use https for this site, for the next X amount of time". This message should only be sent when visiting the site over https. Therefore if you do not redirect in the first place, then a lot of visitors may not even realise you have a https site and so will not get the HSTS instruction.
HSTS is mostly used as a way to change the default of a website to https, and to prevent man in the middle (MITM) attacks which might attempt to keep you on http: e.g. if you connect to a hacker's wifi network and go to your bank website, they will not be able to hijack this connection if it's done over https but will be able to if it's done over http, so attackers will intercept the http request and stop the redirect happening, to keep you on http and intercept all messages to and from your bank.
You can "preload" the HSTS instruction in web browser's code, which gives even more security, as you don't need to visit the site over https first to get the HSTS instruction. This should be caveated that there is basically no way back from this and this should only be considered if you really understand HSTS. There are many, many, many requests to remove sites from Preload list which takes a minimum of 3 months for Chrome (no guarantees for other browsers) and makes your site completely inaccessible during that time if you are not on https. So there is a real danger here! Particularly if some of your site is served over https (e.g. www.example.com) but some of it is not (e.g. intranet.example.com). This is a danger of HSTS as well but even more dangerous with preloading.
The other point to note is that many web agents will not use HSTS and especially not preload lists (e.g. Search Engine Crawlers, older browsers... etc). So again HSTS should be used on top of, instead of as a replacement to, a redirect.
HSTS is a great security measure and should be used by all sites (once they have stopped using http completely) but, like most security measures, does come with its own risks. So make sure you understand it before deploying it. I hate sites and tutorials that say turn it on without explaining it and the risks. In theory a site using HSTS may no longer need to redirect, but in practice it still will need to for the first visit and agents that don't understand or implement HSTS.
To summarise:
Always use redirects.
Strongly consider HSTS, but read up on it first, and start with a low max-age, and without includesubdomains and preload - until you truly understand what they mean.
if running a high risk site, then consider submitting your site to HSTS preload list as a high level of security, but again be aware of risks here. Only do this if you really understand HSTS and feel like you need this level of security.
I have installed a (non wildcard) SSL certificate so my website can use HTTPS. When I try to request resources from HTTP urls I get error-message like:
Mixed Content: The page at 'https://example.com/' was loaded over
HTTPS, but requested an insecure stylesheet
'http://resources.example.com/style.css'. This request has been
blocked; the content must be served over HTTPS.
I get that it probably is a bad practice according to all kinds of opinions people might have when it comes to mix http and https, but I only ask for static resources that I don't regard as critical over http.
Tried to google "allow http requests from https with iis" and similar, but can't find a clear answer. Is there a way around this, is it solvable the same way CORS is?
Sorry if the question isn't very smart and if the answer is obvious, but I lack quite some knowledge some when it comes to networking stuff.
stylesheet ... static resources that I don't regard as critical over http.
CSS can include script and script can alter the page, so it is considered critical.
..."allow http requests from https with iis" ...
The decision to deny mixed content is done within the browser. There is no setting which will allow the browser to include mixed content. The behavior on what is considered mixed content differs between browsers and versions, look here for more information from a year ago.
... is it solvable the same way CORS is?
The security model of CORS cares about same origin policy and a server may decide that a specific other side might do a CORS request. But in this case it is the question if the content might be modified in transit by anybody (i.e. man-in-the-middle attack).
I've read OWASP's HSTS cheat sheet at
https://www.owasp.org/index.php/HTTP_Strict_Transport_Security#Browser_Support
and also watched the related video:
https://www.youtube.com/watch?v=zEV3HOuM_Vw
but still I can't understand how this helps against man-in-the-middle attacks in case of user typing http ://site.com. OWASP claims it helps.
Let's imagine the following scenario: the middle man gets request from victim: http ://site.com. Then he fires HTTPS request himself to https ://site.com and returns content to the user, stripping the HSTS header. All further user input is visible to the attacker.
In my mind, there's no way to protect against MITM unless we're using HTTPS from the beginning.
Does HSTS header really help against MITM attacks?
HSTS helps only if the user agent has visited the site before and there was no interference from a MITM at the time of the first visit. In order words, you are vulnerable the first time you go to the site, but never again.
Since you are still vulnerable the first time, HSTS is far from perfect. But it's better than nothing, since it does protect from an attacker who targets you AFTER you have already visited the site before.
(Except if the user was careful to use https the first time: in that case they are protected the first time and also protected against forgetting to use https on all subsequent visits.)
Firefox is also working on an HSTS preloaded list: http://blog.mozilla.org/security/2012/11/01/preloading-hsts/
The browsers typically maintain the HSTS information in an implementation-dependent secure store of some form. Of course with Firefox and Chrome the code is browseable. See for example https://code.google.com/p/chromium/source/search?q=stsheader&origq=stsheader&btnG=Search+Trunk