This question already has an answer here:

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.

marked as duplicate by Xiong Chiamiov, forest, Benoit Esnard, ISMSDEV, Rory Alsop Mar 15 at 22:41

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 16
    How exactly would the user have a cookie if there's never been a first request? – chrylis Mar 13 at 0:41
  • attacker intercepted the first request and gave his own cookie – Muhammad Umer Mar 13 at 0:49
  • 10
    In that case the cookie is not a secret that you need to protect, is it? – R.. Mar 13 at 1:00
  • 1
    @MuhammadUmer What R.. is trying to say is that your site should be able to tell the difference between cookies it generated, and cookies the attacker generated, and should only honor cookies it generated. This is necessary, but not sufficient, to protect you against several other attacks as well as the one you asked about. – zwol Mar 13 at 17:40
  • 1
    OP, Why is the attacker giving you his cookie? That would log you in to his account (which compromises the attacker's security, not yours, making him not the attacker anymore). – NH. Mar 13 at 18:59
up vote 17 down vote accepted

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.

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.

  • 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 at 20:53

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.

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.

  • if there is man in middle, he can support http version of app. – Muhammad Umer Mar 13 at 23:09

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.

  • once user has been given a cookie that belonged to hacker, then if user connects to server with that cookie over https, then to server it's another request from hacker. even if server doesn't assign cookie over http (manually or by adding https only flag) hacker as man in middle can assign cookie to user. – Muhammad Umer Mar 13 at 17:53
  • I'm not sure I understand the scenario - that would give the intended victim access to the site under the hacker's identity, wouldn't it? Which wouldn't accomplish much. – zwol Mar 13 at 17:55
  • yes, and it compromises data in many scenarios. Ex: you are registering, usually server repopulate form if there is a mistake and highlights which field is wrong. Now you as a user, fill out all personal details even password, then you make a request, suppose there was an error, and as soon as you send data i as hacker also go to registration form and server returns the form filled with all data. So you didn't need to login to leak information. – Muhammad Umer Mar 13 at 17:59
  • I think I see what you're getting at, although the registration scenario doesn't quite work for me (if they're logged in as the hacker, they're not registering for a new account, are they?) This is getting into the land of social engineering attacks: no technical measure can prevent the hacker from lending the victim their own client device "just for a minute", in hopes that they will accidentally type some secret information into the hacker's account... – zwol Mar 13 at 18:10
  • you get assigned cookie when you login, but before that, at login cookie is regenerated – Muhammad Umer Mar 13 at 18:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.