secure redirect from https to http - security

I have a site which after the initial login pages (in https) should redirect to a http site.
I have noticed the session cookie is not carried over between the https and http requests.
What would be a secure way to do this?
Right now as an interim solution I generate a one time unique key to use the first time I move from https to http. This, after verified, re-creates the user session.

What would be a secure way to do this?
There isn't one. At best you end up sending session tokens in the clear and are open to session hijacking. At worst, you expose the user to a MitM attack (even on the pages that both you and the user think are secure, as long as they got there from a http only page).
Serve the entire site over HTTPS. The overhead isn't that high and it removes so many potential security pitfalls.

Related

If all our sites are secure (HTTPS), is setting the "secure" flag on cookies redundant?

If all our sites are secure (HTTPS), is setting the secure flag on cookies redundant?
Are there any pros or cons of setting / not setting the secure if we only have secure sites in our setup?
No, it is not redundant.
Consider the following scenarios.
Situation normal:
User --> Your Website (example.com)
Man-In-The-Middle situation:
User --> MITM --> Your Website (example.com)
If your website listens on port 80 for plain HTTP, and port 443 for HTTPS, then the MITM would have to pass the HTTPS traffic from the User to Your Website as pure TCP data, otherwise the User would get a certificate warning due to the fact the attacker does not have the private key for the example.com SSL/TLS cerfificate.
However, they can still intercept plain HTTP traffic on port 80. Therefore if example.com sets the cookie
AuthenticationSession=0d8d7050f48dc858975c48d32796cd2e5bad2d18
without the Secure flag, the attacker can still intercept this on port 80.
If your website does not listen on port 80 the situation is as follows.
User -tcp80--> MITM
User -tcp443-> MITM -tcp443-> Your Website (example.com)
So, although there is nothing listening at your end on port 80, the attacker could inject the following
<img src="http://example.com/foo.jpg" />
into another request the User makes:
User -tcp80--> MITM --> example.org
Which causes the following to happen:
User -tcp80--> MITM intercepting example.com
sending the cookie to the attacker for example.com
Note that http://example.com:443 will also cause the cookie data to be sent before the server realises it has not gotten an HTTPS handshake, exposing the cookie in the clear:
User --plain HTTP over tcp443--> example.com
In this situation the attacker does not have to be a Man-In-The-Middle, they could just be passively observing the connection to example.com.
Once the attacker grabs the main authentication cookie for a site, they can effectively hijack the User's session and be logged in as them.
If you want to make the Secure flag redundant, implement an HSTS policy. This informs the browser never to connect to Your Website over plain HTTP until the max-age has expired (say 180 days).
Therefore any attacker trying to inject a plain HTTP URL in an image tag will have this changed to HTTPS by the browser, and therefore will render unreadable by anything other than the server. This is known as a 307 internal redirect:
This is [the browser] saying
“I’m not even going to issue that request, instead I’m going to change
it to HTTPS then try again”
However, as a defence-in-depth approach and to provide support for older browsers, I would still include the Secure flag.
Cons? You will be sending the number of bytes within the string "; secure" extra, but only when the cookie is set. And if you need to use the cookie over plain HTTP, you cannot.
If all our sites are secure (HTTPS), is setting the secure flag on cookies redundant?
No, it isn't.
The secure flag prevents the cookie from being sent over HTTP.
Even if your server doesn't listen on port 80 at all (and most HTTPS sites also have an HTTP site that redirects to the HTTPS side), clients which try to connect to port 80 can be subject to man-in-the-middle attacks.
Pros
It protects the cookie
Cons
It costs an insignificant number of bytes.
The point of the secure flag is for the browser to never send the cookie over plain http, regardless of whether the application developer intended to send it only over https. Consider an attack where for example in an html editor form, an attacker can insert images. If he adds an image with a http://server source, the cookie will be sent plaintext unless set as secure. Of course there may be countless other ways to try and inject a plain http request.
If the application server only listens on tcp/443, that's more difficult for an attacker (he could still try things like http://server:443 and see how fast the server drops the obviously invalid connection). It's still the best practice to set all cookies as secure.
So it's not only about man in the middle.

Does HTTPS protect from session riding?

In typical session riding scenario attacker makes victim machine to send HTTP request to web site they are already logged in, for example tricking victim to open link in the case of CSRF attack. Browser includes the session cookie (and all other cookies for that site) in the HTTP request, thus attacker can execute any - possibly malicious - operation victim is authorized to perform.
HTTPS encrypts the whole packet, thus making it impossible to read the content, including headers and cookies. But does it protect from session riding attacks, or will the browser still include the cookies and use correct encryption automatically?
will the browser still include the cookies and use correct encryption automatically?
Yes. A CSRF attack works because the browser treats the request just like any other the user would normally want to make. Both HTTP and HTTPS requests are sent as usual with all cookie data. That's why it's up to the server side of the application to compensate with tokens.

Why is it okay to transmit authentication/session cookies over plaintext?

We all know that it's bad to transmit usernames and passwords over plaintext, since they can be easily viewed by anybody looking at the packets, so we use HTTPS to encrypt this data.
I've noticed that many websites just use HTTPS for the login form and use regular HTTP for all other pages (such as StackOverflow). Couldn't somebody see the cookie (like a session cookie) returned from a login form and inject that into their own web requests? Although it won't expose the username and password, it seems like they could impersonate another user by doing this.
Let's say I'm snooping into my friend's internet connection. After my friend authenticates in HTTPS, the server and my friend begin communicating over HTTP and transmit the cookies in plaintext. What is preventing me from using this cookie?
Nothing is preventing you from using the cookie and stealing his sessions. It's a very poor security practice to send cookies over HTTP. In fact this very weakness was used by the Firesheep Firefox extension that made headlines a few years ago. Since then some sites (notably Facebook and Gmail) have moved to HTTPS only. Other sites should follow suit.
It is not really. If an attacker steals the cookie and then uses it, this is known as Session Hijacking.
StackOverflow are aware of this problem and have been looking at moving towards HTTPS everywhere (site network wide).
To prevent a cookie from ever being sent over an insecure connection, the Secure flag should be set. This will stop the browser from sending it over HTTP connections, even if an attacker tried to make it leak from their own site (very easy to do, an attacker could just include <img src="http://www.example.com/anything.jpg" /> in their own site to cause an unsecure cookie to be sent over HTTP and conduct a MITM attack).

HTTPS handshakes are slow. What is a good alternative, to improve the user experience?

HTTPS is slow to start up, especially on low-bandwidth and high-latency connections, or on low-spec machines. Unfortunately it seems to be the standard method for securing logins used by all major websites.
But a lot of websites we usually visit simply to read information. If we only occasionally want to make a write/update, then waiting to get logged in is an unnecessary time overhead.
The most upsetting example for me is:
Github. I often want to visit a github page just to read a project's overview or view a file. But I must wait for the SSL handshake, even if I don't want to do anything related to my personal account. Github always redirects my browser from HTTP to HTTPS. Why?!
I understand a secure connection is important to authenticate a user account. But when this impacts the user experience of simply viewing public pages, we should try to work out an alternative (and encourage major sites to adopt it).
Here is a possible workaround (1):
Allow users to make HTTP connections to our website, so we can present pages quickly without the need for an SSL handshake.
Allow the login to occur after the page has loaded. Perhaps an Ajax request over HTTPS could authenticate the user, and provide relevant updates to the page. (Is this fundamentally insecure? Edit: Yes, it is not fully secure, see answer below.)
Another alternative might be (2):
Instead of long-lived cookies over HTTPS, use a combination of long-lived one-time-key cookies for persistent login, and short-lived cookies for non-linear browsing, over HTTP. Replace them frequently. (This may be less secure than HTTPS, but more secure than normal long-lived cookie usage over HTTP.)
Do these solutions seem secure enough, or can you suggest something better?
(It might not be a coincidence that I am writing this from somewhere near Indonesia, which is a long way from the USA net!)
Workaround #1 in the question cannot provide full security to the first page, because a man-in-the-middle attack could have injected or modified scripts on the page before the login occurs.
Therefore we should not ask for a username/password on the HTTP page. However, the HTTPS Ajax operation might be able to inform the user that a persistent login session has/can be restored. (A script could then replace all HTTP links on the page with HTTPS links.)
But even if that succeeds, we still should not fully trust any user clicks or <form> POSTs originating from the first page. (Of course, requests to view other pages are fine, but it might be wise to reject updates to settings, password, and finance-related actions.)
This technique could at least be a way to perform the HTTPS setup in the background, without making the user wait for initial content. (StackOverflow uses something like this procedure.) Hopefully the browser will cache the HTTPS connection, or at least the keys, avoiding any delay on subsequent requests.
Here is one alternative I can think of, albeit slightly restrictive:
Allow browsing of public pages over HTTP, but don't perform any user login. This avoids all security concerns.
The 'Login' link would then send us to an HTTPS page, and may be able to recover the user's account automatically from a long-lived HTTPS cookie.
Make an option available "Always log me in through HTTPS", for users who are not bothered by the handshake overhead, and prefer to be logged in at all times. Note that a cookie for this setting would need to be set on the HTTP domain, since it needs to work without the user being logged in!
In reality, we would probably offer the converse: default to the existing prevalent behaviour of redirecting to HTTPS automatically, but provide an opt-out "Do not always switch to HTTPS for login" for those users wishing to avoid the SSL handshake.
But there are still issues with this approach:
Unfortunately cookies are not namespaced to the protocol (http/https). We can mark cookies as "secure" to prevent them ever being sent over HTTP, but some browsers will wipe them entirely if an HTTP request does occur. One way to keep the cookies separate would be to use different domains for unauthenticated and authenticated access to the site. But then we find ourselves violating REST, with two different addresses pointing to essentially the same resource...
Can this be resolved?

HTTP pages are removing my secure cookies

I have a site with mixed HTTP / HTTPS. When the user logs in, she gets two cookies:
a regular cookie with her (signed) username, login expire time, and an "insecure" flag
a secure cookie with her (signed) username, login expire time, and a "secure" flag
note that if you don't have the secure/insecure flag within the signed content, an attacker can intercept the regular cookie and then send it as the secure one (my first implementation made this mistake)
I use the regular cookie on HTTP pages (just for showing her name while she browses the marketing portion of the site). Then I use the secure cookie when she's on HTTPS pages (any user-specific pages).
I got the idea from Secure cookies and mixed https/http site usage.
Everything works great, except that when the user navigates from an HTTPS page to an HTTP one, all of the secure cookies get deleted - which means that they can't go back to HTTPS pages after visiting even a single HTTP page. I should mention that there is a "301 Moved Permanently" that redirects the user to from HTTPS to HTTP.
My site isn't clearing the secure cookie. I know that the browser shouldn't send me the secure cookie while the user is looking at an HTTP site, but I expected the cookie to stick around for its lifetime, and get sent if the user ends up on an HTTPS page again.
I'm getting this same behavior on Chrome, Firefox, and IE. Any tips? I hope this isn't the expected behavior...
Welp, that's embarassing. Here's what my problem turned out to be.
When the user tried to visit an HTTPS site from an HTTP one, their request would start as HTTP
I would check their login credentials (which would fail, because the secure cookie wasn't there), then redirect them to HTTPS. My "require login" and "require HTTPS" systems were separate (a bad design now, but it was convenient in the bad old days where the login cookie wasn't secure)
I thought my secure cookie was being deleted because the Chrome cookie browser doesn't show secure cookies when the page being shown is HTTP. The cookies were there all along.

Resources