39

Suppose that http://example.com/<foo> systematically redirects to https://example.com/<foo>. I enter http://example.com in my browser's URL bar, and I see a page load and the URL bar now displays exactly https://example.com/ (no Unicode hack, no whitespace hack, etc.). I verify that this is the case (most users won't, but assume that in this case the user did). Further assume that my browser isn't vulnerable to URL bar faking. Also assume that the SSL certificate is valid.

In this situation, can I trust that from now on my session is not vulnerable to any man-in-the-middle attack? Could a MITM on the initial HTTP connection have injected something — a cookie, a hidden frame, whatever that would compromise the subsequent apparent HTTPS session?

This is a subcase of How secure is redirecting user from http://normal.bank.com to https://secure.bank.com?, I'm after more details for this specific case.

Gilles 'SO- stop being evil'
  • 51,415
  • 13
  • 121
  • 180
  • 1
    Great question, though I do believe that the biggest threat would be the 'systematic redirect'. – David Houde Nov 03 '13 at 10:24
  • 1
    [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 'SO- stop being evil' Nov 12 '13 at 00:06
  • Been a security IT consultant for 15 years, and I just have to comment THIS IS AN EXCELLENT QUESTION! Wish I could upvote twice. – John Wu Nov 13 '13 at 07:01
  • 1
    This is worth a look, re: the SSLSTRIP exploit: http://security.stackexchange.com/q/64979/41913 – Craig Tullis Jan 03 '15 at 23:29

5 Answers5

11

As far as I can see, there are two vulnerabilities here:

  • The Secure flag isn't set. The initial HTTP request will leak the session cookie either from a session created by the instance at http://example.com or from a previous session created by the instance at https://example.com. The same leaked session identifier will be reused -> The attacker will have access to the session.

  • The initial HTTP request is intercepted and the response is replaced with one that plants a cookie with a session identifier for a session started by the attacker. Subsequent requests will reuse the same cookie. This is a form of session fixation attacks.

In both cases, when reaching the HTTPS instance, the server has no way of knowing whether to invalidate the previous session or not, as the session can be the legitimate one started by the user.

The only solution I see here is to invalidate and recreate the session when a request is made to https://example.com and then use cryptographically-strong tokens in addition to the session cookie with subsequent requests. The token needs to used one time and one time only.

Adi
  • 43,953
  • 16
  • 137
  • 168
  • So if the application does things correctly, everything is fine? Or might the initial HTTP request leak a cookie that belongs to a previous HTTPS session even if the application was written correctly? – Gilles 'SO- stop being evil' Nov 03 '13 at 10:47
  • @Gilles If the application was written correctly (for the sake of this comment, I mean the Secure flag is set), then the cookie will not be passed with the initial HTTP request. A cookie flagged with the Secure flag will only be passed to the domain to which it belongs **if** and only if the connection happens through HTTPS. – Adi Nov 03 '13 at 10:57
  • @Adnan So you are saying that the second attack would be still possible in this case as the attacker could still place a non Secure cookie with the fixated session ID during the HTTP request? – SilverlightFox Nov 05 '13 at 11:33
  • @SilverlightFox The instance at HTTPS should **invalidate** the session and create a new one, always, all the time. In that case, no, the attack isn't possible because the session started by the attacker wouldn't matter anymore. – Adi Nov 05 '13 at 11:48
  • 2
    @Adnan How does the server "know" to invalidate the session? The server will have no way of knowing that the secure flag hasn't been set on the cookie and that the session isn't the original one. – SilverlightFox Nov 05 '13 at 12:48
  • 1
    @SilverlightFox I gave this some thought and you're indeed correct. – Adi Nov 05 '13 at 13:02
  • You usually invalidate the session at the point the user logs in. If your app doesn't have a login (e.g. insurance quote site) the reset needs to be carefully put at the right point. – paj28 Nov 05 '13 at 19:52
  • @Adnan: Actually, the secure flag in a cookie only determines whether the browser will *present* the cookie. The web server doesn't care whether the connection is secure. Otherwise you'd have a heck of a time getting SSL offloading to work! Fortunately my SSL offloading load balancer will issue the redirect before the request even hits the application, so there are no cookies involved at that point. – John Wu Nov 13 '13 at 07:06
  • @JohnWu I believe I never stated otherwise. Actually, that's pretty much what I said in my comment. "A cookie flagged with the Secure flag will only be **passed to the domain** to which it belongs if and only if the connection happens through HTTPS.". But thanks for your contribution anyway. – Adi Nov 13 '13 at 13:08
  • @Adnan: My apologies, I misunderstood the first bullet point in your answer, which seemed to imply that the issue is caused by the lack of a secure flag on the cookie. – John Wu Nov 13 '13 at 15:57
11

As mentionned above, all cookies must be flagged as Secure (Owasp), but also if you expect your users to access to your site only through SSL then you should enable HTTP Strict Transport Security (HSTS - Wikipedia).

The first will ensure that no cookie will be sent over a clear HTTP connection, the latter will ensure that any compatible browser will always, after a first initial access, use HTTPS to access the website (even when the user type HTTP, the browser will automatically replace it by HTTPS without send any HTTP request to the server).

WhiteWinterWolf
  • 19,142
  • 4
  • 59
  • 107
8

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:

  1. Close all other browser windows and tabs - this will make sure that no other HTTP requests are MITM'd and redirected to "example.com".
  2. 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.
  3. 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.
  4. 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.
  5. 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.

SilverlightFox
  • 33,698
  • 6
  • 69
  • 185
  • 2
    Regarding XSS, this can be avoided by adding the HttpOnly flag on the Cookie (this flag is arguably Secure flag best companion ;) ) with prevents scripting language to access it. Regarding the case of the first connection made in HTTP, I expect that there is no session cookie already created when a user connects for the time to the server, so no cookie to intercept. – WhiteWinterWolf Nov 05 '13 at 19:08
  • 1
    @GZBK Correct, but if the attacker is setting the cookie they can omit the "`HttpOnly`" and "`Secure`" flags at will. Depends on the logic - if the app only sets the cookie if not already set then it will be vulnerable. – SilverlightFox Nov 06 '13 at 09:07
  • If I understand correctly, the problem would be the same whether there was a redirection from `http://example.com/` to `https://example.com/`, or the user earlier visited `http://example.com/`, didn't clean the local storage in the meantime, and then typed `http://example.com/`. Right? – Gilles 'SO- stop being evil' Nov 13 '13 at 19:24
  • @Gilles Yes, correct in the case of a cookie (or other local storage) XSS vulnerability, this would be the same if the user either intentionally visited "`http://example.com/`" or if any other HTTP request was MITM'd and redirected. In the redirect scenario it also opens another attack in the case the page at "`https://example.com/`" is vulnerable to XSS in POST data as the HTTP page could return a form that POSTs its payload to the HTTPS URL. – SilverlightFox Nov 14 '13 at 11:22
  • Note: the HTTPS Everywhere plugin ( https://www.eff.org/https-everywhere ) can force all HTTP requests to HTTPS. No need for a local proxy. – Reinstate Monica Nov 13 '18 at 18:37
1

Following your premise that the SSL connection has been established with the correct domain (and assuming neither your server nor the browser has any vulnerabilities), then the user has, via your SSL certificate and his trusted root certificates, verified that the page he loaded from your server arrived without tampering.

I see the following gotchas:

  1. A man-in-the-middle attack is obviously possible if the interceptor can forge your SSL certificate. So if you have shared it (with your CDN? with the rogue admin at your web hoster? with the coworker who is legally prohibited from admitting he was subpoenaed for the keys?), this is actually a possible attack vector. It could also happen if you generated weak keys in the first place (maybe your system was low on entropy or used a broken random number generator?).

  2. Not a single one of the root CAs the browser is configured to trust may be compromised. Note that there are typically lots and lots of them and only one compromise is required for the man-in-the-middle to forge an apparently valid SSL certificate for your domain. Also note that some users may be at the whim of their vendor who may (like Microsoft) push new root CA certificates on demand, theoretically permitting any (lawful?) man-in-the-middle attack that Microsoft (or any of the CAs) can be persuaded to support. We can, of course, hope that only the good guys have that much power over corporations.

  3. Even seemingly unrelated vulnerabilities can obviously negate the entire argument, even those that may be called a feature rather than a bug: Imagine the man-in-the-middle initially serves a webpage over HTTP that causes the browser to switch to fullscreen display, and then imitates a typical browser window. Will your hypothetical super-dilligent user notice that the address bar and its contents are only an elaborate emulation of his browser's address bar...?

  • None of this addresses my question. As stated I assume that the SSL session is correctly established and that the user is observant enough. – Gilles 'SO- stop being evil' Nov 13 '13 at 19:22
  • Sorry for apparently missing the point. Of course, if the SSL session is correctly established with the potential man-in-the-middle hence removed, then your question is automatically answered: SSL then protects you from the man-in-the-middle. Things like previously injected iframes, cookies, etc., should be caught by securely written code (e.g. mixed-content warning in the browser, server code not vulnerable to faked cookies and not setting any that could be set or sent via http). –  Nov 13 '13 at 19:35
1

Since the initial request was sent over HTTP; there are a large number of possible attack vectors available that do not depend on cookies or session state, and would be unaffected by a subsequent redirect to HTTPS, even with a server-supplied HSTS header.

While I'm not a full-time web security specialist, here's a list of possible attacks made possible when an attacker is able to MITM the original HTTP request.

1) Send 301/302 redirects to intermediate URLs to set up/install malware outside of the browser. This can include keyloggers, etc. Very valuable as the attacker can "cherry pick" victims going to a site of interest. When the malware is deployed on the target, a final browser redirect is sent as expected to the client, and the movie goes on like nothing happened.

2) Use the same vehicle to attack the browser itself. There is the opportunity here for the attacker to perform browser-specific actions like installing a malicious plugin.

3) Like above, but exploit any holes available to change the browser configuration. This could be used to enable information leakage via a covert channel like search hints or keyword completion. Or combine this with option 1, and configure the browser to proxy SSL through code executing locally.

4) Load the target SSL page in an iframe and exploit XSS weaknesses in order to obtain and exploit session credentials once the victim logs in.

There is a wide range of difficulties in the above scenarios and they all rely more or less on weaknesses in particular browser versions. Many of the scenarios may be more difficult than other easier attack vectors. There is the utility of employing focused exploits depending on available information in the original request's headers, like user-agent, that could be attractive.

I'm sure there are other wide categories of attack I'm missing but this is a start on exposure that an initial HTTP to HTTPS session can open up.