0

I work both on client and server. When developing, my client runs on http://localhost:3000/ while my server runs on https://local.somedomain.com. The server sends a cookie like

set-cookie: a=aB5Th....;Path=/;Expires=Sun, 02-Aug-2020 11:26:36 GMT;Max-Age=5184000

This cookie is needed for a download link looking like

https://local.somedomain.com/api/v2/ExportSomething.xlsx

however, it isn't there. As the server didn't specify a domain, it might make sense. OTOH, according to this answer, "You can't modify the cookies of one domain using a servlet or JavaScript hosted on another domain, for security reasons", and I don't want to set any cookie for any domain except the one the server runs on, so I'm asking why to specify anything when there's no choice?

Filtering "Has blocked cookies" in Chromium devtools shows nothing, which I'd interpret as "everything is fine, cookies came through". Am I wrong?

The strange thing is that it used to work one or two weeks ago, at least in Chromium (and I'm very sure about that as I worked a few hours on the export). Now it works in none of the four browsers I have tried. Any explanation?

Assuming it's necessary to specify the domain when setting the cookie, is this comment correct?

Boring details

  • every request sets the cookies in the same way
  • no requests beside the above download link use cookies
  • CORS is obviously needed and works and every request gets handled the same way
  • there are no other servers involved

Update

I've just tried cookie.setDomain("local.somedomain.com") and also this with a leading dot and it didn't help.

I also tried leaving out the Max-Age (which also removes Expires which was otherwise added automatically) and it didn't help either (someone claimed that only session cookies work on localhost).

maaartinus
  • 44,714
  • 32
  • 161
  • 320
  • afaik if you don't need to set a domain, the cookie will be for local.somedomain.com. Is it correct that you see the cookie in the server response of the Chrome debugger, but *not* in the Application -> Cookies -> https://local.somedomain.com? Do you have extensions possibly blocking something? – Simon Jun 03 '20 at 12:38
  • @Simon Correct, I can see the cookie as above in the Network tab (or using curl), but it's missing in Application / Cookies. I tried four browsers, two of them freshly installed, so there were no extensions. – maaartinus Jun 03 '20 at 12:50
  • Could you quickly check if anything changes when you start Chrome with `--enable-file-cookies` ? – Simon Jun 03 '20 at 13:19
  • The fact that all 4 browsers reject the cookie indicates at something more general. What are you using as local certificate for HTTPS? Are you possibly using a non-trusted CA? – Simon Jun 04 '20 at 06:44
  • @Simon I'm using a valid Let's Encrypt certificate, obtained in the same way as we do in production. I though, using `http://localhost:3000` for the client could be the culprit, but `http://192.168.100.7:3000` doesn't work either. I also tried to access the server with plain HTTP as `http://local.somedomain.com:10080` and `http://localhost:10080` and other combinations, none worked. – maaartinus Jun 04 '20 at 07:43
  • right, if the certificate were buggy the browser would complain anyway, that was a wrong path. Is it something like this here? https://stackoverflow.com/questions/43865038/browser-wont-store-cookie (cross-domain Ajax requests) – Simon Jun 04 '20 at 11:57
  • @Simon I'm using fetch with `{mode: 'cors', headers: {authorization: ....}, credentials: 'same-origin'}` and the cookie doesn't get sent with the request... but this doesn't matter as my fetch requests don't need it (they have the `authorization` header), only following the link `` does need it. This may be somewhat related, but I guess, the problem is that the cookies doesn't get stored at all. Damn.... that was it.... – maaartinus Jun 04 '20 at 16:38
  • @Simon The cookie wasn't *accepted* because of `credentials: 'same-origin'`, which is [documented](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) as "Send user credentials (cookies, basic http auth, etc..) if the URL is on the same origin as the calling script". I don't care about *sending* the cookie with the request, I only need it to be *received* so it can be sent with a link click request. – maaartinus Jun 04 '20 at 16:41
  • @Simon If you can make any sense of it, feel free to write an answer and I'l accept. – maaartinus Jun 04 '20 at 16:44

1 Answers1

1

Possible reasons for such behavior (that I can think of):

  1. The browser settings reject all third-party cookies (if localhost receives a cookie from local.somedomain.com, that would be considered third-party)
  2. A browser extension is blocking the cookie
  3. The local.somedomain.com server response does not include the necessary CORS headers to allow localhost to receive the cookie. (Access-Control-Allow-Origin must be present and not set to '*', Access-Control-Allow-Credentials must be present and 'true')
  4. Google is messing with you

That last point is actually not a joke, and most likely the cause here. Google has been tweaking the "SameSite" rules for cookies in Chromium, documented here: https://www.chromium.org/updates/same-site

An a related case on SO: Confusion regarding SameSite changes with Chrome

Simon
  • 2,994
  • 3
  • 28
  • 37
  • FTR: My solution is to add request header `credentials: window.location.hostname.match(/local(?:\.|host)/) ? 'include' : 'same-origin'` to my fetch request, so it's secure unless served locally. It works.... till the next funny change. – maaartinus Jun 06 '20 at 11:26