这是indexloc提供的服务,不要输入任何密码
Skip to content

Safely migrating existing web app cookies to Partitioned #78

@GREsau

Description

@GREsau

TL;DR: Is there a recommended process for migrating a web app to issue cookies as Partitioned which does not break ongoing cookies/sessions?

We currently have a big, old, complex, monolithic web app which uses cookies mostly for authentication. Our app is sometimes used in a cross-origin iframe e.g. embedded in a CRM, and sometimes used in a top-level context (and sometimes both, in the same browser session).

To avoid being broken by third-party cookie blocking, we are intending to add the Partitioned attribute to all cookies issued by our app. Being unable to share cookies between the iframe and top-level context is a bit of a problem, but we're mostly working-around it with some (unfortunately slightly hacky) popups and window.opener shenanigans.

Our biggest problem is finding a way to safely roll-out the change to make cookies Partitioned in a backward-compatible manner (and forward-compatible, in case we need to temporarily roll-back the change), which we need to do before browsers actually start blocking third-party cookies. Some of our enterprise customers have quite slow-moving browser update policies, which means our solution should ideally still work for browsers that don't understand/respect the Partitioned attribute.

Naively making all new Set-Cookie headers have the Partitioned attribute would cause problems for users who have ongoing sessions at the point we apply the change, e.g.

  1. A user has an unpartitioned cookie auth=some.session.data
  2. We update our app to include Partitioned in all Set-Cookie headers
  3. The user tries to log out, causing the server to send a response header like Set-Cookie: auth=; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Partitioned
  4. Because the existing cookie in the browser is unpartitioned, the browser does not delete the cookie, so the user remains logged in despite their best efforts

We can work-around this specific case by, when issuing Set-Cookie header with an Expires value in the past (i.e. when deleting a cookie), duplicate the header - once with Partitioned, and once without. This ensures that we delete the cookie no matter whether it was issued as Partitioned or not - although it does violate the recommendations of RFC 6265:

Servers SHOULD NOT include more than one Set-Cookie header field in the same response with the same cookie-name.

However, we still have a problem when trying to update an existing cookie without deleting it, e.g.

  1. A user has an unpartitioned cookie auth=some.session.data
  2. We update our app to include Partitioned in all Set-Cookie headers
  3. The user's session data changes (e.g. when it is renewed) causing the server to send a response header like Set-Cookie: auth=renewed.session.data; Partitioned
  4. Because the existing cookie in the browser is unpartitioned, the browser does not replace the existing cookie - it instead adds a new cookie with the same name
  5. Subsequent requests from the browser include both cookie values in the request header, e.g. Cookie: auth=some.session.data; auth=renewed.session.data

In this case, we would generally want the server to always use the most recently-set cookie value. But with the current browser behaviour, we would need to rely on this always being the last value for the cookie name - this is also against RFC 6265:

Although cookies are serialized linearly in the Cookie header, servers SHOULD NOT rely upon the serialization order. In particular, if the Cookie header contains two cookies with the same name (e.g., that were set with different Path or Domain attributes), servers SHOULD NOT rely upon the order in which these cookies appear in the header.

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