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

Portals #331

Open
KenjiBaheux opened this issue Dec 4, 2018 · 18 comments

Comments

@KenjiBaheux
Copy link

commented Dec 4, 2018

こんにちはTAG!Bonjour le TAG!

I'm requesting a TAG review of:

Further details (optional):

You should also know that...

  • Background for this work:
  • TAG finding
  • AMP blog post
  • WICG thread
  • Demos at Chrome Dev Summit with a prototype: this might help understand some of the use cases.
  • There is an experimental implementation in Chrome but it's missing key features. We expect to have something useful behind the flag in a couple of weeks.

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify: KenjiBaheux, jeremyroman, lucasgadani (because the repo is temporary)

@kenchris kenchris self-assigned this Jan 22, 2019

@travisleithead travisleithead self-assigned this Jan 22, 2019

@plinss plinss self-assigned this Jan 22, 2019

@dbaron dbaron self-assigned this Jan 22, 2019

@plinss plinss added this to the 2019-02-05-f2f milestone Jan 22, 2019

@cynthia cynthia self-assigned this Jan 22, 2019

@torgo torgo added the extra time label Feb 5, 2019

@torgo

This comment has been minimized.

Copy link
Member

commented Feb 5, 2019

On our f2f agenda for Wednesday 6-Feb.

@hober hober self-assigned this Feb 6, 2019

@dbaron

This comment has been minimized.

Copy link
Member

commented Feb 6, 2019

We had a 45-minute discussion of this at our Tokyo face-to-face (Wednesday 2019-02-06, 14:35 to 15:20); the minutes should be available tomorrow. One of the outcomes was that we're hoping to get a little more information added to the explainer that we'll then read and probably have some more feedback on.

We'll want to come back to this at some point in the future.

@dbaron

This comment has been minimized.

Copy link
Member

commented Feb 7, 2019

I think a few of the things we discussed were:

  • We need to get a clear idea of how this differs from <iframe>
    • this will both provide input into the decision about whether it should be an attribute on <iframe> or its own element, and
    • this will also help review what's actually going on.
  • There was a bunch of discussion about things such as whether something loaded in a portal behaves for a bit like it's in a unique origin, and then transitions to being the real origin... and if so how that would work. I don't think the sense of the room was that it was clear that any of the options discussed were workable, but we didn't even understand which option was being suggested (hence the previous comment).
  • a bunch of other things (see the minutes)
@lucasgadani

This comment has been minimized.

Copy link

commented Feb 8, 2019

Thanks for the feedback.

I've looked through the notes, and would like to address some of the points discussed:

  • Why are we proposing this as a new element instead of an attribute on <iframe>:
    • Immutability of the frame tree: The web platform contains many assumptions about the immutability of the frame tree, in particular, the fact that a frame's parent never changes. Chrome experimented in the past with magic iframes, which allowed some iframes to be reparented. This has caused many issues that have lead to the removal of the feature.
    • In order to mitigate some of the risks, we are proposing that portals should not have their WindowProxy's exposed to their embedders. In particular, this implies that they would not be part of the same unit of related browsing contexts, and the only means of communication between a portal and its embedder would be via asynchronous APIs (such as postMessage). This also has other advantages, as it would allow implementers to use separate threads/processes for content embedded in a portal, resulting in better performance.
  • At least for the initial version of portals, we are planning to have a page embedded in a portal behave more or less like a tab, so any privacy-preserving pre-rendering would have to be guaranteed by the embedding page. That means that things like state or storage would be allowed inside the portal (as its real origin) and our expectation is that the embedder would inspect the content being served (either via a CDN or SXG) in order to guarantee the user's privacy. In the future, we'd like to explore other options, such as restricted storage and network access in order to lower the requirements on the embedder page to guarantee privacy, but it's important to note that the embedder page will always need to cooperate with the portal to some extent in order to achieve privacy preserving pre-rendering.
@othermaciej

This comment has been minimized.

Copy link

commented Feb 9, 2019

That means that things like state or storage would be allowed inside the portal (as its real origin)

That sounds like a privacy showstopper for browsers that try to limit cross-site tracking.

@cynthia

This comment has been minimized.

Copy link
Member

commented Feb 9, 2019

I’m assuming the concern is about cross-site tracking through mechanisms like URL query parameters? (I’ve seen Facebook do this.)

(Since window isn’t exposed, seems like this would be the easiest mechanism to exploit)

@othermaciej

This comment has been minimized.

Copy link

commented Feb 9, 2019

@cynthia To expand on this a bit:

The portal host can send any information it wants to the <portal>, either by encoding it in the URL, or by sending it via postMessage(), since it has access to postMessage() the guest browsing context. This could include the URL of the page, or a logged in user ID.

Why is that a problem?

Many browsers deny access to cookies and other state in a third-party context, including cross-origin iframes. Safari has done so for a long time, and continues to expand those protections with various forms of partitioning and complete blocking. Firefox is moving in this direction as well.

So if a site passes info to an <iframe> in a browser with tracking protection, the origin inside the frame won't be able to associate that with a tracking cookie. For example, if a social or video embed is also a very popular site that many users are logged into, it won't be able to associate this page visit (or whatever other info got passed) with your login cookie.

Per @lucasgadani, the plan for <portal> is that content inside the portal gets full access to state and storage. This would completely break that privacy protection. If browsers implemented this proposal, and if embeds switched from iframe to portal embedding, they could completely bypass tracking protection and would once again be able to freely track users across the web.

(This concern does not apply to browsers that lack any built-in on-by-default tracking protection, such as Chrome.)

@lucasgadani

This comment has been minimized.

Copy link

commented Feb 11, 2019

Thanks for the feedback @othermaciej. I completely agree with you that browsers that already support tracking protection through a storage API should continue to do so inside a portal. In fact, this is something we have described in the explainer.

That said, as you mentioned, Chrome does not currently have any built-in tracking protection, and given that our implementation is on top of Chromium, we are trying to keep our scope manageable, so we are not tackling the storage access just yet on our implementation.

At this point, our main focuses are:

  • Solving the origin attribution problem.
  • Providing a richer API that allows developers to implement faster navigations and more interesting page transitions.
@jeremyroman

This comment has been minimized.

Copy link

commented Feb 11, 2019

It seems to me that third-party content inside a portal could be restricted in a similar way to third-party iframes in those UAs, as long as those restrictions could be lifted on activation.

If I understand correctly, WebKit's mechanism does have a way of lifting storage access restrictions at runtime already. Do you think it would be fundamentally incompatible with this approach?

@othermaciej

This comment has been minimized.

Copy link

commented Feb 12, 2019

@jeremyroman Unfortunately, I think restricting in a portal and then lifting those restrictions on promotion is not workable. So this would remain a showstopper for Safari (and maybe Firefox too, not sure of their tracking protection details these days).

To expand a bit: we have a way of lifting storage restrictions based on an API call for the site, with user consent (it pops up an alert). It's called Storage Access API. Mozilla also implements this API. Lifting storage restrictions transparently without any interaction by the site would likely not work. Sites would get a mix of data from different storage partitions if they were not prepared for this happening. Or they might see only the stale info. The site has to know to reload the relevant state, which is why we ask embeds to opt into this. Based on this, auto-promoting portals to unrestricted storage when they get promoted to full screen is likely not viable.

@jeremyroman

This comment has been minimized.

Copy link

commented Feb 13, 2019

@othermaciej As I understand it, Safari's model allows for certain interactions (like a user gesture, conditionally paired with a user prompt) to change the UA's answer as to whether storage access should be granted to content which was loaded in a third-party context, and an API for authors to indicate that the document is prepared for a change in its storage access.

Portal activation is conceptually similar to navigating the browsing context (possibly cross-origin), and as I understand it Safari's model does grant storage access to the document that is navigated to. Given that, would something like this work (deferring the actual access change until the document requests it)?

onload = async function() {
  const supportsStorageAccessApi = !!document.hasStorageAccess;
  const canPersonalize = !supportsStorageAccessApi || await document.hasStorageAccess();
  if (canPersonalize)
    populateWithPersonalizedContent();
  else
    populateWithGenericContent();
};

onportalactivate = async function() {
  if (hasBeenPersonalized || window.portalHost)
    return;

  // This was activated into a top-level context, so the UA can
  // reasonably approve this storage request without prompt.
  await document.requestStorageAccess();
  populateWithPersonalizedContent();
};

There's a more uncommon case in which a nested portal is promoted into a context which is first-party to the top-level context (A->B->A becomes A->A) where it might be useful for the author to be able to request storage access but accept a silent refusal instead of triggering a user prompt, but I don't see that case being common at all.

@othermaciej

This comment has been minimized.

Copy link

commented Feb 13, 2019

@jeremyroman I am not sure if I fully understand what your script is trying to do, sorry.

I think you are suggesting that webpages could be modified to request storage access when promoted from a portal to top level, and that access could be always granted and without the need for a user action or user consent. This wouldn't confuse those pages with unexpected mixes of storage. But it also wouldn't work in unmodified webpages. They would end up always stuck on restricted/partioned storage even after promotion, even in this implied proposal. Remaining stuck on the partitioned storage is also a privacy risk, because it would give what appears to be a top level page access to a partitioned storage in a particular domain. A site could rewrite itself to always use immediately activated portals to effectively gain cross-site tracking capability.

The one thing I can think of that might work for privacy purposes is to completely deny all storage access (even cookies) while in the portal, but allow the site to request storage access on activation as you suggest. I am not sure of the web compatibility of this approach.

@jeremyroman

This comment has been minimized.

Copy link

commented Feb 13, 2019

@othermaciej

I think you are suggesting that webpages could be modified to request storage access when promoted from a portal to top level, and that access could be always granted and without the need for a user action or user consent.

Yes, this is what I'm suggesting.

But it also wouldn't work in unmodified webpages.

Yes, it wouldn't be transparent to unmodified documents. This isn't the only way in which a document may have its context meaningfully changed by transitioning from being embedded to not, so we're still contemplating whether content should have to opt-in to being loaded in a portal context (which reduces surprise, since it gives a signal that authors have given some thought to the consequences), or opt-out (for reasons similar to frames, content must be able to refuse to be embedded).

Remaining stuck on the partitioned storage is also a privacy risk, because it would give what appears to be a top level page access to a partitioned storage in a particular domain. A site could rewrite itself to always use immediately activated portals to effectively gain cross-site tracking capability.

I admit I don't really understand how what you're proposing here would allow pervasive tracking, but if so, having the UA choose to provide no storage access instead of partitioned storage in such cases seems like a viable approach to me.

@dbaron

This comment has been minimized.

Copy link
Member

commented Mar 13, 2019

So one of the recent additions to the explainer was:

How does this work in browsers that restrict third-party cookies?

We imagine that in such cases, the browser would provide functionality for gaining access to first-party cookies (and other storage) at the author's request after activation. For instance, the browser could allow using the Storage Access API for this purpose.

This doesn't seem sufficient for anything that works by keying storage to the pair of the toplevel origin and the frame origin (known as "double-keying"). I'm not sure which (if any) browsers use double-keying today for which kinds of storage, but it's certainly been something that's been discussed in the past.

This would break double-keying because it would transition script from being in one pair to another, and allow matching the storage from one to the storage from another.

I don't see an obvious solution to this within the double-keying model.


Additionally, I still don't think the explainer answers the key question of how this differs from iframe. To consider a few of the many possible examples: Is the document in the portal able to request permissions? Does feature-policy delegation from the containing document still matter? What about the various mechanisms referenced in the first two comments of w3ctag/design-principles#41?

I don't think we necessarily expect complete answers at this stage of the design, but if not answers it would be good to at least understand your current intentions and how you plan to make those decisions.


I agree that using a new element name rather than an attribute is convenient since it means you don't have to worry about the portal-ness changing dynamically; however, there are certainly other ways to restrict dynamic changes. And it still seems quite concerning given how much this has in common with iframe.

@kenchris

This comment has been minimized.

Copy link

commented Apr 3, 2019

iframe is one of the features that has required a lot of work to get right (it is a bit alien on the platform and has resulted in a lot of corner-cases) and which is referred to in multiple places and different specs.

How are you going to handle all of these, like feature-policy, as pointed out by @dbaron above.

We are a bit afraid that this feature will land and it will be a multi-year effort to make it integrate properly in the web platform, similarly to iframes.

I think that you can calm our nerves by going through specs mentioning iframe like HTML and look at all the cases and see if things would work as they are for portals or need monkey patching.

Like you need to define how this works for browsing contexts:
https://html.spec.whatwg.org/multipage/browsers.html#windows

Also check all cases involving iframes like fully active etc.
https://html.spec.whatwg.org/multipage/browsers.html#fully-active

@jeremyroman

This comment has been minimized.

Copy link

commented May 13, 2019

Apologies that we haven't been more responsive in this discussion recently. We do realize that there are significant unresolved issues here (including whether the feature ought to be exposed as a new tag name or be controlled by a content attribute on the existing <iframe> element).

We intend to follow up on these concerns shortly, and though we are experimenting with the feature in Chrome, we have no intention of shipping with this feedback unaddressed.

@domenic

This comment has been minimized.

Copy link
Member

commented May 13, 2019

To @kenchris's point, I want to note that in my role as HTML spec editor, I've been really, really happy and excited about the idea of portals as "iframes done right". Although popular articles or explainers may focus on the flashy features like transitioning the URL bar or adopting your predecessor, @jeremyroman and others have put a lot of thought into the foundations. For a spec that is still in the experimentation stages, it's quite solid and integrates well with existing primitives.

For an example of what I mean by "iframes done right", iframes have many features that complicate their model. Those features can be convenient at times, but in my opinion don't pull their weight for the complexity they add.

The biggest of these is synchronous access to the framed document. This has caused huge spec complexity, security, and implementation hurdles, which we are still sorting out today. Portals omit that, in favor of simple postMessage-based communication. Other such features are things like srcdoc, the observable initial about:blank transition, the weird load event (still buggy), etc.

I do think there are still some things that need porting, such as the story around feature policy/sandbox. But even that will be a simplification opportunity, most likely; instead of allow + allowfullscreen + allowpaymentrequest + sandbox, I'm hopeful we'll have something more coherent and unified.

Finally, the biggest missing piece is session history integration, tracked at WICG/portals#19. That will affect things like "fully active", indeed. This is complicated by known issues with the session history spec. Perhaps more generally, there are probably other things where the notion of "nested browsing contexts" should apply to portal browsing contexts as well (e.g. update the rendering?). Portals add more complexity here on top of iframes due to the activation possibilities. Still, I am confident that because portals allow us to start with a clean slate, and because they decrease the synchronous observable interactions, the editors will be able to find and spec a model that works well.

I hope this helps!

@jeremyroman

This comment has been minimized.

Copy link

commented May 15, 2019

Here is an expanded explanation of our current thinking on the question of introducing a new <portal> element, compared to adding an attribute to the existing <iframe> element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.