Sessions don't work in Chrome but do in IE

February 06, 2019
web

I observed an interesting thing today while helping a client. The problem was presented as:

We have a bunch of Chrome users having issues where a session variable is not working between page requests. We set the variable on one page, it is not defined on the next page request. If we tell them to try another browser, such as IE or Edge it works fine.

I have seen problems like this for many years and it doesn't often end up being a difference in the browser implementation, but rather the difference is that the user has essentially cleared their cookies when they try another browser. In this case the client confirmed that the problem went away when they use a new Incognito Chrome browser window.

Attacking the problem

Next I fired open Chrome developer tools to see what was happening. This particular website was serving requests over both http (port 80) and https (port 443). The session cookie (JSESSIONID in this case) was getting the secure flag set when the request came over https, a request over http would not get the secure flag set.

When the secure flag is set by a cookie the browser must not send that cookie over an insecure transport like plain http. This is the essence of what a secure cookie does.

Eureka

Even though a request over http would cause Tomcat or ColdFusion to set a new JSESSIONID cookie, Chrome will not store that cookie if it already has a cookie with the same name and the secure flag is set.

So here is what happened:

  1. User requests https page, sets JSESSIONID with secure flag.
  2. User makes request to non-secure http page, the JSESSIONID is not sent because it is a secure cookie. The server creates a new session, and tries to set a new JSESSIONID cookie, but the browser ignores this new cookie because it already has a JSESSIONID.
  3. User navigates to another page over non-secure http they do not have a session cookie to pass, repeat step 2.

Do all browsers work this way?

Both Chrome 71, and Firefox 64 prevent a secure cookie from being overwritten on plain http. I tested Edge 42 and it does not work the same way, it will overwrite the secure cookie with the non-secure cookie. Safari 12 works similar to Edge.

My assumption was that the browser would maintain separate cookie values for the secure origin and the non-secure origin in this case. My assumption was not correct on any modern browser. I tested a few old versions of Chrome and found that this implementation was added somewhere between Chrome 37 and Chrome 60 (I didn't want to test each version, I will leave that as an exercise for the reader ;-).

Here's an easy way to test a browser using httpbin.org a site/api for testing HTTP clients, it is useful because it serves requests over both plain http and https. Additionally their set cookie feature will set a cookie with a secure flag when requested over https:

If you see test_secure=2 over http then the browser is overwriting the secure cookie, otherwise you will not see the test_secure cookie over http.

How do you work around this?

Fixing this is pretty straight forward, you have to redirect all http traffic to https and the problem is solved. There is not really any valid use cases for serving content on both http and https that I am aware of.



Related Entries

1 person found this page useful, what do you think?

Post a Comment




  




Recent Entries



foundeo


did you hack my cf?