12

You could use HSTS to tell browser to always use HTTPS in future requests.

You could use Cookie Secure flag that from now on only send cookies over HTTPS.

You could use DNS based redirect but only after HTTP request has gotten there..

My question is how do you make sure user always visit the site as HTTPS and never send any data over HTTP even the first time.

Edit:

Given lack of solution to this, I think browsers should automatically first send https request by default and it doesn't work then downgrade.

Edit:

Without comments the question, as is, and the answers do not make sense. Both seem to talking about different things so I want to give some context.

  1. A user types in http://abc.com for the first time
  2. abc.com is not in hsts preload list
  3. So browser goes ahead and make a request over non ssl path
  4. Request is intercepted by Mitm, and attacker makes request on behalf
  5. server says update to ssl and send registration/login form
  6. attacker upgrades HIS connection to server to SSL but doesn't tell user and proxy html to user. (doesn't tell user to upgrade to https because hacker provided cert would be invalid)
  7. User inputs everything into http page
  8. Hacker may even pass in its cookie to User.
  9. Allowing for future data access until cookie is revoked.
Muhammad Umer
  • 715
  • 7
  • 10

5 Answers5

17

In summary of the comments (and by replacing my previous answer): as long as sslstrip is possible the attacker can impersonate the user and control the session while the browser thinks that the user controls the session. Only HSTS can prevent sslstrip and only HSTS preload can prevent sslstrip on the first request (before getting a HSTS header).

Thus HSTS preload should be the way to go as pointed out correctly in the answer by Benoit Esnard.

The problem is, HSTS preload can take months to be available for a new domain since an updated list ships only with a new version of the browser (at least in case of Google Chrome).

In other words: there is no solution which can be implemented within a short time.

jrtapsell
  • 3,169
  • 15
  • 30
Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • 1
    If the choice of domain is yours, you could pick one with a preloaded eTLD (e.g. `app` or `dev`). No need to wait for your domain to get added to the preload list. – jub0bs Mar 03 '21 at 13:12
14

Submit your website to the HSTS preload list.

The HSTS preload list is a list of hostnames embedded in browsers, allowing them to know which websites must be crawled as HTTPS only, thus preventing any non-HTTPS request.

Benoit Esnard
  • 13,942
  • 7
  • 65
  • 65
  • 1
    While being a good idea it can take several month for the site to be HSTS preloaded according to the link you provide: *"Note that new entries are hardcoded into the Chrome source code and can take several months before they reach the stable version."*. Thus, it is more a long term investment but not a quick solution. – Steffen Ullrich Mar 12 '18 at 20:53
6

What you are describing is called a Session Fixation Attack (Wikipedia link).

In short, the problem is that the attacker can give you a Session Identifier cookie. You log in using this cookie and the server will associate your identity with this cookie.

The attacker still knows your session id cookie and can pretend to be you with the server. Attack complete.

To defend against this, the server must change the session id cookie when somebody logs in. The attacker is left with a stale worthless cookie and can do nothing.

Not all web frameworks lets you change the session cookie. If this is a problem, you can use a different cookie for this purpose, a separate "authenticated cookie" that the framework doesn't know about. This cookie too must be changed every login.

Stig Hemmer
  • 2,403
  • 10
  • 14
1

You can't prevent the cookies from getting submitted over HTTP the first time, but you can take steps to minimize the damage that could be done by this. The basic principle is that you never, ever honor anything submitted over HTTP, and whenever you receive sensitive information in cleartext, you treat that information as compromised.

Set up your site to redirect from HTTP to HTTPS, and start sending Strict-Transport-Security headers. (You don't have to go for preload until you're good and ready; what I'm about to say will work regardless.)

Then, whenever you see cookies submitted over cleartext HTTP, invalidate all of those cookies on the server side. Don't try to kick them out of the browser's cookie jar at this point, because it isn't guaranteed to work for several reasons (a cleartext HTTP response can't manipulate cookies tagged Secure, older browsers might ignore max-age=0, the man-in-the-middle might strip Set-Cookie altogether in order to keep the victim using the compromised cookie). But don't honor them when they appear in a subsequent HTTPS request. At that point (i.e. only when you have a secure channel established), issue a new session token and require the user to log in again.

Similarly, if you see your login form being submitted in cleartext, don't just invalidate the session cookie, lock the account. Don't redirect the account recovery, login, or registration form from HTTP to HTTPS; instead, issue an error message, instructing the human to fix the URL by hand (it's like a captcha, but it's for bypassing URL rewriting in sslstrip ;-). And any page that should be accessible only to logged-in users should redirect to the front page, not to HTTPS-itself, when accessed via cleartext.

In addition, make sure that your session cookies are both unforgeable and meaningless. Most Web frameworks will do this for you automatically nowadays, but if you haven't got one, the simplest construction that will work is: each session cookie is a large (64 bits might be enough, 128 is definitely enough) random number, generated by a cryptographically secure RNG, plus a message authentication code signing that number. You can use a symmetric MAC for this, because the cookie only needs to be authenticated by the site, which is the same entity that issued the MAC, so it will know the same secret both times. If a cookie comes in with an invalid MAC, ignore it, regardless of how you got it -- pretend you never got it at all. (This even supersedes the rule about invalidating cookies that come in over HTTP. You don't want the attacker to be able to force-logout people by forging requests.) But if the MAC is valid, then you use the random number as the key to a database table recording all of the actual information associated with a user session.

It is also best practice not to issue any cookies at all until someone tries to log in. That makes it much harder for a MITM to get their hands on a valid cookie, and it also makes it easier for you to comply with GDPR.


After reading the discussion on the other answers, I now realize OP is concerned with a very particular scenario: a new user to the site accesses it for the very first time through a man-in-the-middle, who is terminating HTTPS, stripping out HSTS and rewriting all links, and relaying the site unencrypted to the hypothetical new user. Against this, indeed, the only thing that can possibly help is HSTS preload. In the absence of HSTS preload, the new user's account will be "born compromised", as it were, and the attacker will know everything about it: not just the session cookie, but the username and password, and the email address used for account recovery, and every bit of personal information that the victim entered. This is nasty and, alas, more plausible than you might think.

But if you get just one chance to interact with the user over a channel that isn't being actively tampered with, you can push HSTS and secure session cookies and all the advice above will be useful.

zwol
  • 647
  • 1
  • 4
  • 12
1

Given there isn't a complete way to stop clients from trying to connect to HTTP, possibly with cookies...our challenge is to find ways to reduce how often it happens.

One approach is to not support HTTP at all. Let any HTTP requests time out (no redirect, nothing). This reduces the chances of other sites linking to your HTTP address, since such links won't work. Over time, hopefully everyone who links to your site will link directly to HTTPS.

Krubo
  • 789
  • 5
  • 9