As well as @GZBK's and @Adnan's excellent answers, one other thing I've thought of is the case of the application being vulnerable to XSS on output of a cookie value.
Say normally the cookie value is output unencoded, but as the cookie was normally set over HTTPS and would not be subject to MITM it was not a danger as the user could only attack themselves. However, if the HTTP request was intercepted and the cookie was poisoned with an exploit for this XSS vulnerability, this could be a possible attack vector in this scenario.
Of course this is not the non HTTPS request including a redirect being vulnerable because this cookie could be set even if "example.com
" did not listen on port 80 at all: An attacker could MITM any other HTTP request the victim made, redirect them to "http://example.com
" which the attacker also intercepts and returns the response to redirect the user to their original website, but only after the "example.com
" cookie has been poisoned.
can I trust that from now on my session is not vulnerable to any man-in-the-middle attack?
The only really secure way to browse over an untrusted network is to disable all protocols from the browser other than HTTPS (e.g. configure a local proxy but set the browser to use an invalid port for all protocols other than HTTPS). HSTS can help, but if the first request is intercepted (e.g. using the technique described here even before you have even thought of visiting "example.com
") you would still be vulnerable.
Update below in relation to new question in comment:
[I forgot to enter the bounty comment] I'm asking from the perspective of a user (though it is interesting to know what the site/app should be doing, too). In what circumstances does typing example.com in the browser's URL bar directly direct me to https://example.com/? In what circumstances does typing http://example.com/ directly direct me to https://example.com/? If there is a request to http://example.com/ first, what bad things can happen, and how as a user can I know whether bad things are happening? – Gilles
If there was an active HSTS record for "example.com
" (either pre-loaded or if the user had visited before) and the user typed either "example.com"
or "http://example.com"
in their address bar they would go directly to "https://example.com"
without any request being made on HTTP.
When a web application issues HSTS Policy to user agents, conformant user agents behave as follows:
Automatically turn any insecure links referencing the web application into secure links. (For instance, http://example.com/some/page/ will be modified to https://example.com/some/page/ before accessing the server.)
If the security of the connection cannot be ensured (e.g. the server's TLS certificate is self-signed), show an error message and do not allow the user to access the web application.
If there was no HSTS record and the user typed "example.com"
or "http://example.com"
in their address bar an insecure request would first be made to "http://example.com
" which would normally reply with the "Location: https://example.com/
" header. This will cause the browser to load the HTTPS URL. If the user wanted to make sure nothing had been injected or altered and that all that happened was that the "Location
" header was returned they should clear all state information. The process for doing this should be as follows:
- Close all other browser windows and tabs - this will make sure that no other HTTP requests are MITM'd and redirected to "
example.com
".
- Disable JavaScript in their browser. This will ensure there is no script running that is setting cookies on an interval. For example if there was an XSS vulnerability through a cookie value, the injected script could be ensuring the cookie value remains set by resetting this every few seconds. AKA a zombie cookie.
- Clear cookies, any local storage and any browser plugin data (e.g. local Flash/Silverlight). This will remove most of the state information for the site.
- Press refresh on the browser. This will ensure the current page load was not a POST because the user would get a warning message. The POST may have injected content into the page if there are any XSS vulnerabilities.
- Re-enable JavaScript if required.
Obviously this is a lot to go through and it may be easier for them do simply use the proxy technique as described earlier to disable HTTP and to start with a clean browser (e.g. new Incognito session).
If a user is browsing over an untrusted network then they can never be 100% secure. There is no easy check for tampering unless everything is in a known state (hence either starting from a clean state/HTTPS or removing all state information). Yes they could manually check cookies, but with clever techniques an attacker could clear the cookie once the script has been embedded in the page.