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

User Activation Delegation through postMessages #347

Closed
3 of 5 tasks
mustaqahmed opened this issue Feb 22, 2019 · 21 comments
Closed
3 of 5 tasks

User Activation Delegation through postMessages #347

mustaqahmed opened this issue Feb 22, 2019 · 21 comments
Assignees
Labels
Resolution: withdrawn The requester has withdrawn the proposal

Comments

@mustaqahmed
Copy link

mustaqahmed commented Feb 22, 2019

こんにちはTAG!

I'm requesting a TAG review of:

Further details (optional):

You should also know that...
While Chrome needs this API to fix regressions caused by UAv2 (#295), the concept of delegation here is independent of the model in UAv2. The delegation here can be used with any user activation model, including Chrome's old model (user gesture tokens).

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 [github usernames]
@alice alice self-assigned this Feb 26, 2019
@mustaqahmed
Copy link
Author

We need to review this quickly: we have got at least one regression that would be fixed by this API.

@alice alice added this to the 2019-03-19-telcon milestone Mar 19, 2019
@torgo
Copy link
Member

torgo commented Mar 19, 2019

Feels like there needs to be more exploration / mitigation of the potential privacy issues considering we are talking about user state here?

@dbaron
Copy link
Member

dbaron commented Mar 19, 2019

Is https://github.com/mustaqahmed/user-activation-delegation/ the repo where you want github issues to be filed?

@dbaron
Copy link
Member

dbaron commented Mar 19, 2019

And so I don't forget, the issue I was hoping to raise was that I'm concerned that being able to pass the state to another frame means that duplication of creating the activation state becomes a sort of privacy vulnerability. In other words, if, say, a user agent treats both mousedown and mouseup as triggering a user activation, then it could have a mousedown observer that transfers its own user activation state to another document, and then it would get activated again on mouseup. So this requires that (a) implementations be both more conservative and more interoperable in how they cause a user activation state and (b) that even with that fixed, it seems like it allows spreading user activation state much more broadly than before, since user activations often come in groups.

@mustaqahmed
Copy link
Author

@torgo: There is no privacy concern here since only information we are transferring here is "whether user is interacting (or has interacted) with a frame". This is a trivial information any page can easily collect today through event handlers and then store/communicate using other APIs.


Thanks @dbaron for highlighting this tricky abusability scenario. Let me explain why I think this transfer API is the safest choice we have:

  • If this transfer API is used in conjunction with UAv2 (TAG review here, successfully shipped in Chrome 72), all user inputs (even multiple clicks) within a time-limit of few seconds already fuse into a single activation, and consuming the activation in any frame already clears the whole frame tree. So multiple consumption is impossible. See the Security Considerations section in our design doc.
    (This solves problem (a) in your post, and prevents (b) too.)

  • If this transfer API is used without UAv2, it's the job of the underlying model to guarantee single consumption with and without activation transfer. We believe that existing non-UAv2 models are too complicated to be able to provide this guarantee; for example Chrome had this serious bug with cross-process postMessage despite many years of effort (got fixed through UAv2).

  • For user activation, there is no interop today even with a plain postMessage: see this comparison from 2017. We can't expect interop only with the transfer option here. This has been broken for many years, and will need a long-term plan to fix.
    (A related note on interop: not all browsers trigger user activation through mousedown. In Chrome we have a bug to possibly drop mousedown to match Firefox. Spec discussion here.)

To emphasize, our long-term goal here is interop with user activation. In Chrome 72 we proved through UAv2 that a simple, token-less, easy-to-implement solution works for the Web. We encountered a few breakages, for which the transfer API proposed here is a workaround. Once we are done with both of these successfully, we will encourage other browsers to switch.

@plinss plinss changed the title TAG review request: User Activation Delegation through postMessages Mar 25, 2019
@torgo
Copy link
Member

torgo commented Mar 26, 2019

@mustaqahmed We take privacy extremely sincerely. Even it's obvious to you that this doesn't impact user privacy, it wasn't obvious to us. We'd like to see user privacy addressed in the explainer a bit more, even if it's just to say "we think this data can be collected in other ways ... [which ways] ... and therefore there is no additional privacy concern." But I also wonder: does this API allow privacy-sensitive information to be collected more easily, and if so, are there any mitigations against potential privacy issues that are built in? Thanks.

@dbaron
Copy link
Member

dbaron commented Mar 26, 2019

Let me explain why I think this transfer API is the safest choice we have

That explanation sounds reasonable to me; I'd hope that dependency is at least clear to implementors from reading the spec or from reading the explainer.

@plinss
Copy link
Member

plinss commented Mar 27, 2019

I'm having serious doubts as to whether the notion of "user activation" should even be exposed to the web platform. This isn't a top-level feature in itself but rather a UA mechanism to control the availability of other features.

If we expose user activation this gives web page developers no indication of which features will be enabled or disabled, and I expect that set of features to be UA dependent and change over time.

What happens when UAs invent new mechanisms to gate features, such as eye tracking or the like? Is this an API we want to support forever?

I'd much rather see improvements to permissions APIs or other mechanisms to get access to, and be able to delegate access to, the individual features that would be gated by user activation.

@annevk
Copy link
Member

annevk commented Mar 28, 2019

I think you're correct that there is variance between implementations, but all implementations do have this notion and for some APIs there is agreement that this notion should be a requirement (e.g., Fullscreen). Given that, the typical follow-up is to refine and standardize.

Now, whether the mechanism Chrome has established works for them is also the model Firefox and Safari want to match is less clear.

@mustaqahmed
Copy link
Author

@torgo: Thanks for raising the privacy implications question from data collection perspective. I have created a detailed privacy consideration doc to analyze your concerns, and linked it from the explainer as well as from the security/privacy questionnaire. Please let me know if this addresses your concerns.


@dbaron: Added a para in the explainer to further clarify the dependency with UAv2.


@plinss: I agree this is a low-level feature but as @annevk commented, all browsers rely on "user activation" for many APIs already. Moreover, many specs refer to this notion. For example, check fullscreen model, also check how many times the phrase appears in the HTML spec.

We have been discussing the spec problem with "user activation" here for a while; this API here is just a follow-up proposal to Chrome's main proposal there to fix the problem. Let's continue this discussion on that issue.

@plinss
Copy link
Member

plinss commented Mar 29, 2019

@mustaqahmed @annevk I'm not arguing that "user activation" shouldn't be a thing. UAs obviously already use that as a signal to gate certain features. That's fine. It's also fine for specs to refer to that, just like specs refer to "private browsing mode" and how things behave differently in that state.

Neither of those mean that the user activation state should be exposed directly via an API (just like there's no API to determine if you're in "private browsing mode"). Frankly as a web developer, I don't care, and shouldn't care, if the page is in a user activated state, what I care about is: "can I open this popup right now?" (or other gated feature). I do not want to check the user activation state and then guess whether or not that's going to impact my ability to open a popup. What about when feature X is also gated by other things, like: is the page installed to home screen? how many times has the user visited the site? how long has the page been open? what's the battery state? what's the network connection like?

There are all things that may gate the availability of a feature today, let alone the things UAs are going to invent tomorrow. (where is the user looking right now? is the device moving at more than xx kph?)

My argument is that the information that web developers need is whether or not the individual feature they're trying to use is available or not, not the inputs that went into that decision.

I also don't have an issue with delegating those capabilities, but instead of delegating the various inputs, delegate the actual capabilities, such as the ability to open a popup, or auto-play a video with sound, etc.

@mustaqahmed
Copy link
Author

I see your perspective from "input vs capabilities" now, thanks. Here are our takes on that:

  • Delegating user activation doesn't exclude the delegating (or even suppressing) capabilities. They are in fact orthogonal. Suppose we would add a "popup delegation" API in future, then we may still have a use-case like "this subframe can open popups but only with its own user activation", right?

  • I see that the ability to delegate capabilities would give developers more fine-grained control on what to delegate or what not to. But the "orthogonality argument" above means activation transfer doesn't take that finer-control away. E.g. a top frame can delegate user input to a subframe, and still say "disallow fullscreen".

  • We have specific cases where developers want to transfer user activation from one frame to a "controller" frame. See the regression I mentioned in my first post above. Here is another example.

In summary, we already have capability delegation today (say <iframe allow=...> attributes), and it's natural expect more from individual API owners. Activation delegation makes this notion more powerful and useful IMHO.

@ojanvafai
Copy link

I think we might be talking past each other a bit in the last two comments because we mean different things by capability delegation. <iframe allow=...> gives permanent delegation rather than only in response to a user activation. This is trying to give temporary delegation of specifically the things browsers allow but only after user activation. If I understand @plinss correctly, he's not suggesting that we merge these concepts, but instead change the mechanism of the transfer.

@plinss is something like this what you were suggesting? (borrowing from feature policy syntax):
// Only transfer activation for the purposes of autoplay popups:
targetWindow.postMessage("handle_click", {allow: "autoplay; popups"});
// Transfer activation for anything that blocks on it.
targetWindow.postMessage("handle_click", {allow: "*"});

I think that's good feedback, but I also think it's confusing because the set of things being allowed here is the set of things that require a gesture, not any general feature. Will think on whether we could (in the future) temporarily delegate any policy controllable by feature policy, but this is the first I've considered that idea...so...I'm not confident it's a good one. :)

@plinss
Copy link
Member

plinss commented Apr 3, 2019

@ojanvafai yes, while I'm not proposing any specific syntax, that's the idea I was trying to get across.

Rather than delegate the gesture, delegate what the gesture enables, this way we're not tying the specific feature that's being enabled to a gesture or any other mechanism, just the fact that the feature has been enabled (because the mechanism for enabling the feature can/will change or be UA specific). It also gives the author more fine-grained control about what can be done in the delegated iframe.

Also, related, rather than have an API that exposes the fact that you've been "user activated", expose the fact that the specific features controlled by the activation state have been enabled (and disabled when the gesture has been consumed or no longer applies). This can either be done by the existing permissions API or by augmenting that API as needed for the transient nature of the permission.

I understand that the features we're taking about here (so far) are the ones currently controlled by user activation, but why not have this be the same mechanism as delegating any other permission?

@mustaqahmed
Copy link
Author

Capability-delegation is an orthogonal concept

@plinss: we already agreed above that user activation is an input not a capability. Now let’s look at why capability delegation is not a solution for your problem:

Rather than delegate the gesture, delegate what the gesture enables, this way we're not tying the specific feature that's being enabled to a gesture or any other mechanism, just the fact that the feature has been enabled.

From privacy/abusability perspective, a capability-delegation-mechanism should not enable the capability unconditionally. Let’s look at popup: if the user's current settings allow popups from origin A and disallow them from origin B, a capability delegation from A to B shouldn’t suddenly allow popups from B, right? A more compelling example is Geolocation: a site that has the user’s permission to silently use Geolocation (because the user chose “always allow” in the past) shouldn’t be able to transfer the silent access to any third-party (say ad) subframes.

Therefore, if we want developers to know if they can open a popup, we would need a separate (popup-specific or generic) API for that. Delegation is not a solution for that.

From a different perspective, each capability has a context, and the whole context can’t be transferred through a capability-delegation-mechanism. This confuses developers even with the “permanent” delegation we have today: does <iframe allow=fullscreen> mean

  • the subframe gets unconditional access to fullscreen (say, w/o user activation), or
  • it gets just the permission to try fullscreen, subject to all regular checks (including user activation)?

Any capability that needs delegation would have its own corner cases, and should address this question from its own perspective IMHO.

Temporary delegation is not activation expiry

@ojanvafai: If we tie the notion of “time” in “temporary delegation of capabilities” with the expiry time in user activation, this becomes problematic because different activation-gated APIs rely on user activation state differently.

If we transfer one capability (say popup) to a target frame, would we retain other capabilities (say, fullscreen) in the sender frame? I think we meant "yes" here, right? Then every activation-gated API would need to be tracked in every frame. This is like a user activation state for every gated API, with complicated logic to sync states during trigger, expiry and consumption. This doesn’t fit our philosophy of UAv2: simplicity of the underlying model for sake of interop. Separating input (user activation) from capability looks like a good tradeoff that maintains simplicity while providing reasonable control...

Fine-grained control on API availability is already there

It also gives the author more fine-grained control about what can be done in the delegated iframe.

I will clarify my last post: we can achieve this through existing means (iframe allow or feature-policy). Using user activation transfer on top of this allows temporary access during “unowned” user interaction (i.e. user activation on a different frame).

@mustaqahmed
Copy link
Author

We are looking again into the use-cases that motivated us, in case there is still a way to hide user activation somehow.

@alice alice added the Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review label May 15, 2019
@torgo
Copy link
Member

torgo commented May 21, 2019

@mustaqahmed we are discussing this issue at our f2f currently. Can you provide any update on the comment you left above? Thanks!

@mustaqahmed
Copy link
Author

Sorry for the delay: we had several face-to-face meetings to find a unified solution covering general capability delegation. We haven't converged to a solution yet, I will share our initial findings in a week.

@mustaqahmed
Copy link
Author

Hi TAG: we are still debating the shape of an API for transient capability delegation. While that is pending, we seem to have converged into the idea that user activation delegation is not the right solution here.

@hober
Copy link
Contributor

hober commented Sep 10, 2019

We seem to have converged into the idea that user activation delegation is not the right solution here.

Okay. Closing this issue; please file a new design review request for whatever alternate solution you come up with. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: withdrawn The requester has withdrawn the proposal
8 participants