Skip to content

Changing which cookies are bound can be complex #227

@drubery

Description

@drubery

In order to prevent SameSite bypasses, the spec checks that you can set a bound cookie before doing any config changes. This could make dropping support for a cookie unnecessarily complex. Imagine a site with a DBSC session that binds a SameSite=Lax and SameSite=None cookie, and they want to migrate their sessions to only bind the SameSite=Lax cookie. Ideally, they could do the following:

  • Make the refresh endpoint serve the JSON config with only the SameSite=Lax cookie
  • Make the refresh endpoint clear the SameSite=None cookie
  • After some time has passed, delete this extra functionality (Note that it's not possible with this simple migration to measure what fraction of the traffic has migrated the session config)

This seems pretty safe with respect to SameSite bypasses because in order to trigger a refresh on the SameSite=None cookie, the deferred request must have included the SameSite=None cookie (eliding possible nuance between the conditions for sending and storing cookies). But they can't do that today. If the request is 3P, the spec says the user agent should reject the new config because it's made in a context where they can't set any bound cookies in the new config. Since they fail to set a SameSite=None cookie, the next 3P request will also trigger refresh, and so on until there's a 1P request. Extra latency on every 3P request is probably unacceptable.

Here are some options that do work today (and may be better overall since sites can measure migration progress):

Migrate at session registration:

  • When users login, give them a new session id and the new config
  • Measure how much of the refresh traffic has the new id instead of the old
  • Drop support for the old sessions once enough traffic has migrated
    This is slow, since you have to wait for a large fraction of users to reauth.

Migrate in two phases:

  • If the refresh endpoint gets a request with no cookies, defensively assume it was a 3P request. Serve a long-lived SameSite=None cookie set to a sentinel value so this client will not trigger refreshes from 3P contexts anymore.
  • If the refresh endpoint gets a request with the SameSite=None cookie set to the sentinel value, we know it was triggered in a 1P context, so update the config
  • Over time, measure what fraction of refresh traffic has the SameSite=None cookie set to the sentinel value
  • When enough traffic has the SameSite=None cookie set to the sentinel value, drop the code to set the SameSite=None cookies and start clearing the SameSite=None cookies instead
  • After enough time, all clients have the new session config and had their cookies updated
    This has the disadvantage of being two phases, but is very observable and probably the best bet if the site has long-lived authenticated sessions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions