Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded 3rd-party IFrame content opening a new tab/window to the same 3rd-party site should have access to same partitioned cookies as opener #82

Open
UselessPickles opened this issue Jan 26, 2024 · 13 comments

Comments

@UselessPickles
Copy link

I have a situation involving integration between two partner enterprise software vendors that is broken by deprecation of 3rd-party cookies. Please bare with me, because this takes quite a while to set the scene and explain the problem.

Setting the Scene

Let's call the two vendors/sites "A" and "B". "A" is the "host" vendor into which "B"'s product is integrated as 3rd-party IFrame content.

Vendor "A" provides the authentication for users, and "B" is configured to redirect to an authentication URL from vendor "A", which then redirects back to "B" with verified user info/tokens/etc. Although "A" does maintain the (first-party) cookies related to authentication, "B" still needs to setup its own session cookies (3rd party, because embedded in a 3rd-party IFrame) after authenticating via "A".

Just to be clear: the intent here is only for "B" to consistently have access to its own cookies within the context of being embedded in "A". There is no intent, attempt, or desire to have access to any cross-site tracking 3rd-party cookies. If site "B" is accessed either as a 1st-party top-level site, or embedded in some other partner site "X", then we explicitly do NOT want to have access to the same cookies or user session across all of those contexts.

So the solution seems obvious: CHIPS! If "B" simply flags all of its cookies as Partitioned, then we should get exactly the behavior we want.

The Problem

However, there is one use case that fails: On some pages in the embedded 3rd-party content from vendor "B", clicking on certain UX controls (links, menu items, etc) will open a page from "B"'s site in a new tab or window. The current behavior of CHIPS is that this new tab/window is a brand new top-level first-party context. So the page from "B" in that new tab/window does not have access to the same partitioned session cookies that were setup by the 3rd-party embedded IFrame of "B' inside of "A".

The resulting behavior is, depending on specifics of how the authentication integration is configured between "A" and "B", either:

  1. The content of the new tab/window simply displays a "not logged in" error page because there are no top-level 1st-party session cookies setup for "B".
  2. The new tab/window redirects to the authentication URL from site "A" because there are no top-level 1st-party session cookies setup for "B". There ARE top-level 1st-party authentication cookies for site "A", so it immediately redirects to site "B" with the verified user info/tokens, and site "B" sets up a NEW session for the user (new session ID, new top-level 1st-party session cookies).

Behavior 1 is clearly bad/broken.

Behavior 2 appears good on the surface, except is is broken in the worst way: subtly. The server for site "B" is a stateful server that maintains session state, including cached calculated results, state of user workflow, etc.. So the new tab/window opened by "B" needs to share the same session to ensure that all side-effects of any user actions performed in the new tab/window are also applied to the session used by the "main" view of site "B" in the 3rd-party IFrame embedded in "A". Very strange, seemingly intermittent, and unpredictable bugs can occur if the same user is logged in twice under different sessions and actively going back and forth between the two sessions, performing operations, and expecting both sessions to stay in sync with each other.

Firefox

It's worth noting that our integration of sites "A" and "B" works perfectly fine in Firefox with its "Enhanced Tracking Protection" set to "Strict" such that it automatically partitions 3rd-party cookies.

A Proposed Solution

If site "B" could open a new tab/window in a way that it "inherits" the 3rd-party cookie partitioning context of its opener, then everythign would work as we desire. The new tab/window would have the same user session in site "B" as the embedded 3rd-party iframe of site "B" that opened it.

I understand there may be security concerns with this, and I understand why the default behavior should be to NOT inherit the cookie partitioning context of the opener. I'm also not an expert on security issues/attacks involving new tabs/windows, but I think it may be reasonably manageable with some simple rules:

A new tab/window will inherit the cookie partitioning context of its owner if and only if both conditions are met:

  1. The opener explicitly requested that the new window/tab inherit the cookie partitioning context (e.g., via some new parameter in the windowFeatures argument to the window.open function).
  2. The URL being opened into the new tab/window is from the same site as the opener (may be a different subdomain on the same site).

Alternative Solutions Considered

  1. Related Website Sets: This is not appropriate for this situation because "A" and "B" are completely different independent companies with no relationship to each other except a partnership deal to integrate their products together. Related Website Sets is for a set of related sites all owned by the same person/company.
  2. Storage Access API: This is not appropriate because we are NOT attempting to access a single user session of site "B" across multiple 3rd-party embeds as widgets in multiple different embedding "host" sites. We specifically want the cookies to be partitioned by each 3rd-part embed context, and also separate from a top-level 1st-party access to site "B". Even if used as a hacky workaround, it would both introduce architectural/implementation complexity to site "B" to properly implement Storage Access API, and the placeholder pages that require the user to click on something to request access would completely break the presentation of the integration. There are other issues, like some browsers requireing that the user had somewhat recently visited the embedded site as a tope-level first party site in order to grant access. With the "A"/"B" integration , a user would NEVER directly visit site "B". All access to site "B" would be through embedded 3rd-party iframes in site "A". The intent is for "B" to be tightly integrated into "A" such that it appears as a single cohesive application, and we have gone to great lengths to ensure that it is marketed and presented in every way possible such that users are not even really aware that it is an embedded 3rd-party integration.
  3. Don't embed "B" in "A" at all. Instead, configure "A" to launch "B" in a new tab/window so that "B" is in a top-level first-party context, and any new tabs/windows opened by "B" will have access to those same tip-level first-party cookies. This is not acceptable at all (see 2 above where I explain the tight integration).
  4. Rework web app "B" so that it never opens a page in a new tab/window: This is really the last resort. It won't be easy. It won't be good UX. There's good reason that "B" opens some pages in a new window. It may be a complex screen where the user can perform complex operations, but they also need to be able to simultaneously look back at the opener page for reference, and common use cases may be to have both the opener window and the new window arranged on one or two monitors side-by-side for simultaneous viewing of both. Making changes in the new window communicates changes back to the opener to keep the two in sync, and it is important to be able to review the summarized representation of data in the opener window as changes are made in the new window.

Reproducing/Demonstrating The Problem

Due to the nature of enterprise software, and the fact that we have currently opted out of 3rd-party cookie deprecation and have enrolled into the grace period, it will be a challenge to present a workign example of this problem. With some coordination, it would be possible to temporarily set up one of our test accounts to demonstrate this problem and share private URL and login info. Please let me know if you'd like to coordinate something.

@krgovind
Copy link
Collaborator

krgovind commented Feb 7, 2024

@UselessPickles Thanks so much for your excellent notes. Indeed, the solution you presented is something we briefly considered on a W3C Privacy Community Group call previously (see privacycg/storage-partitioning/issues/28); but we need to spend a more time studying security, privacy, and user experience implications for such a solution; since the notion of a popup/redirect using a partitioned-by-opener context is a new concept to the web platform. We will discuss this internally and hope to have an update in a few weeks. Note that we are also considering other solutions that leverage the FedCM API as well, so I would recommend that you examine that API as well, if you haven't already done so.

@privacycg privacycg deleted a comment from edik-tlt Feb 12, 2024
@UselessPickles
Copy link
Author

@krgovind I took a look at the FedCM API, and I don't think it would help in this situation. We're not having any trouble with the identification/authentication workflow. The problem is a stateful server session and a session cookie needed to continue the same stateful session across page loads, new tabs, and popup windows. This is a cookie created by the server AFTER the identification/authentication workflow is complete.

Site "B" in my scenario is not an IdP, but a large complicated web application that is embedded in site "A", and uses site "A" as its IdP in this particular integration/configuration. So the authentication cookies will always be "first-party" relative to the "host" site (site "A").

As I mentioned in my initial post, we have already tested and confirmed that we can get the authentication portion working perfectly in this new tab/window use case, but the real problem is that it will create a new independent session on site "B"'s server, causing a disconnect/inconsistency between the opener and the new tab/window.

@srilakshmi-devarapalli-by

Hi Jeff,

Did you find any solution for this?

We also have same situation where our embedded Iframe has window.open - links with same 3rd party site and needs session cookies to allow users.

@arichiv
Copy link

arichiv commented May 14, 2024

Chrome is considering a new proposal which might help with this use case: https://github.com/arichiv/partitioned-popins

@UselessPickles
Copy link
Author

@arichiv Unfortunately, that "partitioned popins" proposal would not help with our situation:

  • Some of our use cases are not "modal dialog" situations. We open pages in new tabs in some cases with the intent that it is independent of the opener, and the user should be able to freely switch back and forth and use both tabs (e.g., we open help documentation in a new tab so that the user can reference help while still having the application open in the original tab). The session cookies from the opener are necessary in the new tab to access the help documentation.
  • For use cases where "partitioned popin" could work for us, this is still not helpful. We need a solution by the end of the year when the 3rd-party cookie deprecation trial ends. The proposal appears to be in early stages, probably not ready by end of year. Even if the proposal gets implemented by end of year, we likely wouldn't have time to rework, test, and deploy our product with "partitioned popins".

We need to make some very tough decisions very soon if no viable solution is provided. "Just don't do that" (i.e., rework our application to never launch a page in a new window/tab that requires session cookies from the opener) is not a practical option. Our integration with our partner will be broken when the trial ends if we do not have a solution.

@srilakshmi-devarapalli-by

Hi @arichiv

As @UselessPickles mentioned, we are also in same situation. Could you please prioritize this?

@srilakshmi-devarapalli-by

Hi @arichiv

Is there a way for us to test popins?

@arichiv
Copy link

arichiv commented May 24, 2024

@srilakshmi-devarapalli-by
Implementation has not yet started. I wouldn't expect a prototype behind a flag before Q3 this year.

@UselessPickles
You mentioned a need for access to cookies partitioned by the opener (e.g., where A embeds B and then opens a tab for B you want that tab to have the same cookies as A+B). You also say you don't want just to have access to unpartitioned cookies via SAA, for example, as the cookies should not be shared if C were to embed B. How do you achieve this now, before third-party cookie deprecation has launched?

Firefox may be working due to heuristics. Chrome is considering something similar: https://developers.google.com/privacy-sandbox/3pcd/temporary-exceptions/heuristics-based-exceptions

In both cases I believe these would provide access to unpartitioned cookies in a third-party context.

@johannhof if I'm missing something

@UselessPickles
Copy link
Author

UselessPickles commented Jun 14, 2024

@arichiv Prior to 3rd-party cookie deprecation, everything "just worked" for us because our cookies are all tagged as SameSite=None, so our cookies were effectively working as cross-site 3rd-party cookies (even though it is not our intent/desire to track anything across multiple embedding "host" sites).

Maybe taking a step back and considering our actual use case and requirements (without the assumption of CHIPS) may help? The partitioned cookies solution feels a bit like a hack to me, but it was also the only practical solution I could find that could potentially work for us. It seems wrong to me that our app should have to declare that all of our cookies should be partitioned 3rd-party cookies when we don't really intend for our app to work as a 3rd-party app. It's really a complete self-sufficient 1st-party app that we want to visually embed in a partner app with some SSO authentication integration. The SSO integration does not require any 3rd-party cookies (it's all redirects between our site and the partner site, with tokens passed as URL params, etc).

I really just want to be able to render our app in some kind of sandboxed 1st-party context in our parter app, as if it were a separate browser tab, but visually embedded. While doing my initial research, I found that fenced frames are probably EXACTLY what we need, but it was not a practical solution as it was still "experimental" and not supported by any other browsers. Has the future of fenced frame become more certain since I initially investigated it nearly a year ago? Are other browsers planning to support it now? Would it be a safe investment to add conditional support for fenced frame (if detected to exist) and trust that it will eventually work on other browsers and work as our one-and-only cross-browser solution to eliminate our reliance on 3rd-party cookies to embed our app in partner apps?

Or is there any other way to achieve such behavior aside from fenced frame? For example:

  • If the "3rd party" app is rendered in an iframe with the sandbox attribute, does that cause the iframe to be treated as a separate 1st-party context instead of an embedded 3rd-party context?
  • If the "3rd-party" app is made available as a custom Web Component that essentially just renders an iframe in its shadow DOM containing the "3rd-party" web app, will this create a sandboxed 1st-party context for that iframe when the web component is included by and rendered in the partner "host" app?

@johannhof
Copy link
Member

@UselessPickles Note that Fenced Frames have certain restrictions that make them unlikely to be attractive for you, such as no access to cookies or storage and limited ways of opening links / popups. You certainly won't be able to use a Fenced Frame to open a pop-up that shares same-site cookie access, which seems to be the main feature you're looking for here?

It's really a complete self-sufficient 1st-party app that we want to visually embed in a partner app with some SSO authentication integration.

I understand that you feel like this is a first-party app by your definition, but by web platform terms this is a third-party embed. The fact that you rely on SSO auth via redirect from your partner shows that your app isn't truly isolated from its embedder (though this would still be a 3P embed without such an auth scheme).

I really just want to be able to render our app in some kind of sandboxed 1st-party context in our parter app

If that's the case (you really just want to render an embedded app inside of a partner site) then Partitioned cookies are what you should use. However, it sounds like you want more than that. You also want this embedded app to be able to open new top-level contexts (a pop-up) which share access to the same cookie jar. As we've said on the thread, this is a reasonable request within certain parameters, but it's not trivial to make it work without violating some privacy or UX requirements. Partitioned Popins are meant to solve similar challenges, though I understand why it doesn't perfectly work for you. We're grateful for this feedback as it helps us improve the API over time.

It's not something I'd usually recommend, but in this case it might be necessary to use the opener relationship established between the embedded context and the popup to pass some authentication parameters. That would not introduce additional user friction, but it comes with a few drawbacks:

  • Passing auth parameters via JS makes your site more vulnerable to credential theft from injection attacks etc.
  • Browser vendors are generally looking into restricting opener relationships in some way as they present privacy leaks, replacing them with concepts such as Partitioned Popins.

Or is there any other way to achieve such behavior aside from fenced frame? For example:

No, if either of your presented options were possible that would be a privacy leak and we'd fix it.

@darkowic
Copy link

darkowic commented Jul 2, 2024

We do face a similar problem with popups having access to a different instance of partitioned storage. I shared the details in an issue that seems to be more appropriate: privacycg/storage-partitioning#28 (comment).

@pshurygin
Copy link

We are facing a very similar issue with our embedded enterprise app, and so far it looks like the only viable solution is the partitioned-popins proposal above. For our use case it would likely be enough(we do not need the full-blown new tabs). But the problem is that the 3rd party cookies might be deprecated before this proposal is implemented and released, and this brings us into a dead end. The only other solution proposed is:

It's not something I'd usually recommend, but in this case it might be necessary to use the opener relationship established between the embedded context and the popup to pass some authentication parameters.

but for me it sounds like it would raise a lot of security-related issues.

I cannot find any timeline for the partitioned-popins feature release and it looks like there is not even 100% certainty it would be released at all. Personally I would expect that 3rd party cookie support cannot be disabled until this issue is resolved, as this will basically make the valid use case like ours broken without any viable and secure workaround. Is this something that's taken into consideration at the moment?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants