Force https entire site without redirecting http to https
There were a plenty of discussions while I was researching how to make my entire site https. The most answers were to redirect http to https (.htaccess file), which is not good, because it's not good to do the same job twice (two requests). Also, the "man in the middle" first takes on http, and I want my site to go directly on https. Is there another way to make your entire site https, and how to do this? For example, when user types in example.com, that example.com automatically goes to https, without redirecting from http or anything else first?
Solution 1:
No. You cannot magically make the visitor's browser choose the right protocol. A redirect is the way to do it.
Solution 2:
http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security allows your server to indicate that the domain should only be accessed via HTTPS. This only applies to subsequent requests, so there'd be an initial HTTP load, but future requests would load HTTPS even if someone explicitly typed HTTP.
IE doesn't support it yet, but all the other majors do.
Solution 3:
As others have said, you can't force users to choose the right protocol. But when the user tries to use HTTP, what should you do? A redirect is also insufficient, because an attacker sitting between you and the client can intercept the redirect, so the client never sees it. The client will continue to send plain HTTP, and the attacker will strip away the SSL layer from the server (SSL stripping attack).
The only sure way to prevent that is to not serve HTTP at all. Don't answer on port 80, except maybe to serve a plain text page directing the user to try again with HTTPS (but not providing a link, which the attacker could manipulate). This will force the user to type https://
into their browser, so they'll initiate the connection with SSL and prevent the MITM attack.
Solution 4:
ceejayoz has the best answer to prevent the specifically mentioned attack here but I want to also point out what a lot of people here are missing which is basically that HTTP has the other part figured out already. You want to do a permanent 301 redirect. This tells the client to make further requests to the new address. So yes, if someone types the wrong URL they will make 2 requests BUT, in the future, a good client is supposed to detect requests to that URL and make the correct request instead to prevent any more wasted requests. The problem is that this is only for that exact URL. HSTS improves upon this scheme by also saying, 'for the next n seconds also do not allow any non-secure connections from this domain'.
Users should not visit sensitive sites at insecure locations. They especially should not signup for them in insecure locations. These are basic user security principals which should be taught just like, 'don't open attachments from untrusted sources'. Which are really the best answer for preventing MiM attacks for sites which have never been visited.
As a side note, some browsers improve upon this by also saying certain known sites always use HSTS. Unfortunately, you can't just add yourself to this list easily.
Further reading: http://coderrr.wordpress.com/2010/12/27/canonical-redirect-pitfalls-with-http-strict-transport-security-and-some-solutions/
http://dev.chromium.org/sts
Solution 5:
Not entirely true: How to use DNS/Hostnames or Other ways to resolve to a specific IP:Port
There is a way, but most browsers don't implement rfc2782.