-
Notifications
You must be signed in to change notification settings - Fork 38
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
Consider not running internal methods in parallel or add "consumes user activation" to registry? #243
Comments
This has come up in the past and I would not be surprised if there were already bugs in said other specs (webauthn example) where actions that should only be run in the main thread are being executed in internal methods. It's a pretty subtle issue for those of us who are not well versed in the browser event model.
We could have the default implementation of the promise-based methods (discover from external source, collecting credentials, etc) be to call the non-promise methods in parallel to avoid having to rewrite every client spec in one fell swoop. Ideally this would come with some expectation that client specs eventually update to implementing the promise methods so we can remove the existing non-promise methods. It can even be done in small chunks, one If you really want to do it (and slice the work up in manageable chunks) -- this seems like the right way to do it and I'll happily provide reviews and set up some time to update WebAuthn.
This might not be enough: e.g. for WebAuthn the standard only requires consuming an activation for create on a cross-origin frame.
If we go this route I feel slightly more inclined to add specific wording on a case-by-case basis like we do for permissions policy before #242, just because of that cross-origin webauthn case. As you point out that means bringing more client-spec stuff into credman which is suboptimal, but if it lets you focus on more important things, it's probably okay too. Overall: I'll support you through option 1 if you want to invest that amount of work, but will also stamp option 2 so we can move on to more substantial work (: |
Interesting. @timcappalli, do you know the rationale for this? This seems like a potential bug for the reasons I outlined above (if UI is presented, then activation should be consumed by top-level frame too otherwise one could trigger, for example, payment request in the same micro-task). (I see that Tim is out on vacation... I'll try to follow up with some other folks around this) |
Found some history around user activation: w3c/webauthn#1801 @stephenmcgruer, can you help me understand the change a bit more? I don't know Web Authn very well... can .create() be called in a first-party context without presenting UI in Web Authn? I'm trying to understand why it's different in third-party contexts. |
Argh... I found more issues with this while implementing... in WebKit, both WebAuth and Digital Cred treat it as not running in parallel until necessary (i.e., we pass the promise). Just for a bit more detail, I don't just want to "consume the user activation", I also want to hook into fully active descendant of a top-level traversable with user attention. I can only do that via having access to the document on the main thread. What if, to keep backwards compat, we add the promise as optional argument... then in the spec we say, if the promise was passed, then you are in control of when you go into parallel... otherwise, run in parallel? We can then reach out to various specs to change their behavior and hopefully get everyone to "choose their own adventure" 🤠 |
Sorry Marcos, this question didn't go to my work email so I missed it >_<. You are correct that I'm not an expert on webauthn, but I understand that there were historical reasons behind webauthn in general not requiring a user activation for either create() or get() calls. I believe there were existing user flows for which the webauthn team wished to make it possible to drop-in replace webauthn for the authentication method that was in use, but that in those flows no user interaction was present to initiate the authentication. (For example, flows where you are redirected to an authentication provider - upon arrival at the new webpage, you no longer have any user interaction). When it came time to do From the Chrome side, we're not unified on this but I think we more and more have the belief that user activation guards are not very significant in terms of protecting users from hostile websites - it's too easy for a website to cause the user to give it interaction. However they can still be useful as an anti-spam/anti-DOS technique (e.g., to stop websites triggering focus-capturing flows repeatedly). That's why we've begun exploring spaces such as 'first call is free' - currently scattered across multiple specs, but maybe one day we'll unify this to a core concept in the user activation spec itself? |
Mozillian driving by... 👋 I don't think that you could guarantee a whether or not a given
I'm not sure if I follow where the optional argument goes exactly. IIUC the caller would need to decide whether to put a promise into the
This matches my personal understanding. This is why requiring and consuming user activation for user-prompts or dialogs is a good heuristic in design. It also has a nice property of making that dialog occur after the user did a thing. Now if that thing is relevant or not to the dialog can't be guaranteed in any way (although PEPC seems to be trying to tackle that) but at least the user can draw some cause and effect. This lets them not do the thing over and over again if they are being spammed.
I think unifying on a principled, unified decision would be nice :) |
Adding the extra column in the registry means we have one more thing to update in cred man that depends on the specifics of each credential type. This isn't that much better than writing the specifics of how user activation is handled for webauthn & digital credentials on credman. If we want to fix this right, why not add a set of internal methods that return (or take) a promise |
Yeah, I'm landing at @nsatragno solution too. I'd prefer not to overload (or have two) methods tho. If we make the promise optional, then we can use it as a switch for to run in parallel or not in Cred Man. |
It might be good to consider not running the internal methods in parallel, and allowing them to be called with a promise.
The problem is that the Cred Man is having to account for main thread behavior (e.g., permission policy checks) that ought to be potentially left to other specs.
Another situation where this has come up is with consuming the user action, which should be done on the main thread.
We could, however, make a hard determination that calling
.get()
(and possibly other methods, if they show UI... like maybe.create()
) should consume the user activation.Alternative, we add another column to the registry table for "consumes user activation?", and we add true/false values to that column (least amount of work... but again brings baggage from other specs into Cred Man... which may be ok)
@nsatragno, how would you prefer we proceed?
The text was updated successfully, but these errors were encountered: