12

In node.js (using Hapi framework) I'm creating link for user to allow my app reading user account. Google handles that request and asks about giving permissions. Then Google makes redirect to my server with GET parameter as a response code and here I have an issue.

Google Chrome isn't sending cookie with session ID.

If I mark that cookie as a session cookie in cookie edit extension, it is sent. Same behavior in php, but php marks cookie as session when creating session, so it isn't problem. I'm using plugin hapi-auth-cookie, it creates session and handles everything about it. I also mark that cookie then in hapi-auth-cookie settings as non HttpOnly, because it was first difference, that I have noticed, when inspecting that PHP session cookie and mine in node.js. I have response 401 missing authentication on each redirect. If I place cursor in adress bar and hit enter, everything works fine, so it is an issue with redirect.

My question is basically, what may be causing that behavior. On the other hand I have to mention that firefox sends cookie after each request without any issues.

Headers after redirect (no cookie with session):

{
    "host": "localhost:3000",
    "connection": "keep-alive",
    "cache-control": "max-age=0",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
    "x-client-data": "CJS2eQHIprbJAQjEtskECKmdygE=",
    "x-chrome-connected": "id=110052060380026604986,mode=0,enable_account_consistency=false",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, sdch, br",
    "accept-language": "pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4"
}

Headers after hitting enter in adress bar (what will work fine):

{
    "host": "localhost:3000",
    "connection": "keep-alive",
    "cache-control": "max-age=0",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, sdch, br",
    "accept-language": "pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4",
    "cookie": "SESSID=very_long_string"
}
simon-p-r
  • 3,623
  • 2
  • 20
  • 35
Alan Mroczek
  • 1,099
  • 1
  • 11
  • 27
  • Please show the code for the redirect. Two things to check: Are you setting rootpath on the session cookie so it can be seen from everywhere on the site? Is your redirect to the exact same domain/port/protocol as the page where the cookie is set? – jfriend00 Nov 24 '16 at 08:47
  • Yes, cookie has path: / and it works fine on every route. Google is making redirect to my site after user hits allow, so I haven't that code. And it is everything fine theoretically because I can hit enter in adress bar and then cookie is sent. Google chrome just isn't sending cookie after redirect from google to my `http://localhost:3000/api?code=code_from_google` but if I copy link and paste it, it works. – Alan Mroczek Nov 24 '16 at 08:53

4 Answers4

15

Strict cookies are not sent by the browser if the referrer is a different site. This will happen if the request is a redirect from a different site. Using lax will get around this issue, or you can make your site deal with not being able to access strict cookies on your first request.

I came across this issue recently and wrote more detail on strict cookies, referrers and redirects.

Richard Garside
  • 87,839
  • 11
  • 80
  • 93
  • 2
    The link to the article is very useful, as it shows why it may not work after being redirected from a third-party authentication provider, which was my problem. Thanks! – Célia Doolaeghe Oct 06 '21 at 09:41
3

This issue is caused by hapi-auth-cookie not dealing yet with isSameSite (new feature of Hapi). We can set it manually, eg.

const server = new Hapi.Server(
    connections: {
        state: {
            isSameSite: 'Lax'
        }
    }
);

But please consider that, by default you have 'Strict' option, and in many cases you may not want to change that value.

Alan Mroczek
  • 1,099
  • 1
  • 11
  • 27
  • 1
    Using `Lax` for SameSite solved my instance of the problem, but I'm curious: what do we need to change about the `cookieAuth.set` → `reply.redirect` sequence to get the cookie back on the redirect request when `isSameSite` is `Strict`? If we reload, we get the cookie. The `set-cookie` is clearly working. It's just that Chrome isn't sending the cookie when redirected, even if the redirect is fully qualified. – Garth Kidd Feb 14 '17 at 01:33
  • I've raised a more complete form of the question above as [`42216700 `](http://stackoverflow.com/questions/42216700/how-can-i-redirect-after-oauth2-with-samesite-strict-and-still-get-my-cookies) – Garth Kidd Feb 14 '17 at 02:13
2

A recent version of Chrome was displaying this warning in the console:

A cookie associated with a cross-site resource at was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure.

My server redirects a user to an authentication server if they didn't have a valid cookie. Upon authentication, the user would be redirected back to my server with a validation code. If the code was verified, the user would be redirected again into the website with a valid cookie.

I added the SameSite=Secure option to the cookie but Chrome ignored the cookie after a redirect from the authentication server. Removing that option fixed the problem, but the warning still appears.

Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
  • 1
    It's not `SameSite=Secure` it's `SameSite=None` and `Secure` set seperately. From MDN: "None specifies that cookies are sent on both originating and cross-site requests, but only in secure contexts (i.e. if SameSite=None then the Secure attribute must also be set)" – Will S Apr 29 '21 at 08:48
  • i.e. `Set-Cookie: a=b; SameSite=None; Secure` – Will S Apr 29 '21 at 08:49
1

A standalone demo of this issue: https://gist.github.com/isaacs/8d957edab609b4d122811ee945fd92fd

It's a bug in Chrome.

isaacs
  • 16,656
  • 6
  • 41
  • 31
  • 1
    I hit this bug using IP address [http://127.0.0.1/site](http://127.0.0.1/site) but not with hostname [http://mysite.local/site](http://mysite.local/site) including localhost - just flagging in case it helps anyone -as it burnt me for an hour or so. – Dazed Feb 08 '19 at 10:27