Hapi: Support SameSite=None for cookies

Created on 13 Oct 2019  ·  13Comments  ·  Source: hapijs/hapi

Support plan

  • which support plan is this issue covered by? (e.g. Community, Core, Plus, or Enterprise): Community
  • is this issue currently blocking your project? (yes/no): no (not until February 4, 2020)
  • is this issue affecting a production system? (yes/no): yes

Context

  • node version: v12.11.1
  • module version: hapi@latest
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): standalone
  • any other relevant information:

What problem are you trying to solve?

I need to deliver a cross-origin cookie that is compatible with the upcoming Chrome 80. See https://www.chromium.org/updates/same-site & https://tools.ietf.org/html/draft-west-cookie-incrementalism-00.

The Secure part is set through the isSecure: true server state option, but there is no way to add SameSite=None.

Note that this issue might better be categorised as bug, since the the current implementation works to deliver cross-origin cookies, but will fail on Chrome 80.

Do you have a new or modified API suggestion to solve the problem?

Change the server state isSameSite: false option to add SameSite=None; to the returned cookie string.

Unfortunately this breaks some not that old browsers including Safari 12 and Chrome 67, so I suspect it needs to be set or not based on the User-Agent header of the request. Alternatively, I need an api to signal which variant I want to respond on a particular request with.

feature

Most helpful comment

For reference, this is the code that's working for me:

const Hapi = require('@hapi/hapi');
const { isSameSiteNoneCompatible } = require('should-send-same-site-none');

new Hapi.Server({
  state: {
    isSameSite: false,
    isSecure: false, // just an example, can also be true depending on your use case
    contextualize: async (definition, request) => {
      const userAgent = request.headers['user-agent'] || false;
      if (userAgent && isSameSiteNoneCompatible(userAgent)) {
        definition.isSecure = true;
        definition.isSameSite = 'None';
      }
      request.response.vary('User-Agent');
    },
  }
});

I'm using should-send-same-site-none to determine if None is supported.

All 13 comments

@kanongil did you find a workaround for this?

@hueniverse Is there a timeline on when 783987e is going to get released?

Next two weeks.

@hueniverse Thanks for your feedback! Can you keep us posted here since this is somewhat of a crucial issue which will kick in once Chrome 80 gets released.

For reference, this is the code that's working for me:

const Hapi = require('@hapi/hapi');
const { isSameSiteNoneCompatible } = require('should-send-same-site-none');

new Hapi.Server({
  state: {
    isSameSite: false,
    isSecure: false, // just an example, can also be true depending on your use case
    contextualize: async (definition, request) => {
      const userAgent = request.headers['user-agent'] || false;
      if (userAgent && isSameSiteNoneCompatible(userAgent)) {
        definition.isSecure = true;
        definition.isSameSite = 'None';
      }
      request.response.vary('User-Agent');
    },
  }
});

I'm using should-send-same-site-none to determine if None is supported.

@mfeltscher Thanks for the code snippet. It is very useful.

I would probably also add user-agent to the vary header of the output as well. Otherwise you could encounter proxy caching issues. This can be done by adding request.response.vary('user-agent') to the contextualize implementation.

@kanongil Good point, adjusted my example accordingly.

@mfeltscher hey! this is wicked cool. I've been fretting over this issue myself, appreciate you sharing your solution.

I'm curious, though: why does your definition set isSecure: false? Was there anything that motivated omitting the Secure attribute from SameSite none incompatible user agents?

I hope this doesn't come across as critical; genuinely asking. I'm betting I'm missing something 😁

@zemccartney It's just an example to show how this can be overridden in the contextualize method. Of course you can just use isSecure: true in all instances (which we actually do).

@mfeltscher gotcha. Thanks for the clarification, much appreciated!

Is there anyway I can use set IsSameSite as None in hapi v17.8.5?

@rahulakurati I recently needed to do the same in an earlier hapi version. You'll need to modify the hapi/statehood package to support the None value for isSameSite, see my commit below for example.

https://github.com/auth0-extensions/statehood/commit/f283770392a4ff476e41b66f731bcda47e05ef9b

@rahulakurati I recently needed to do the same in an earlier hapi version. You'll need to modify the hapi/statehood package to support the None value for isSameSite, see my commit below for example.

auth0-extensions/statehood@f283770

thaank you so much!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hovmand picture hovmand  ·  3Comments

taoeffect picture taoeffect  ·  3Comments

mateeyow picture mateeyow  ·  5Comments

AdriVanHoudt picture AdriVanHoudt  ·  5Comments

RohovDmytro picture RohovDmytro  ·  4Comments