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

Rationale for "untrusted events do not trigger default actions" #160

Open
pipcet opened this issue Sep 27, 2017 · 1 comment
Open

Rationale for "untrusted events do not trigger default actions" #160

pipcet opened this issue Sep 27, 2017 · 1 comment

Comments

@pipcet
Copy link

pipcet commented Sep 27, 2017

I'd like to question the specification on this point: untrusted events triggering default actions is the only way, given current JavaScript, to handle events asynchronously while still permitting some events to invoke default behavior. The "alternative" is to emulate all events, which is cumbersome, error-prone (unavoidably so in the case of user-specific keybindings), and an accessibility nightmare.

With default actions triggered by untrusted events, the matter is simple: call preventDefault synchronously on all events, then run the (asynchronous) event handler and let it decide whether to replay the event, by copying the event data to an untrusted event and dispatching that, or to handle the event itself (not doing anything since preventDefault has already been called).

This used to work.

In essence, we can turn the event handler into an async function with the sole caveat that we need to filter out "trusted" actions synchronously—which makes sense, as malicious code should not be able to delay such actions.

In my application, I would like to support type-ahead as well as on-demand loading of keybindings: the decision whether an event is handled by the keybindings or left to the default action should usually be made instantaneously, but if there is a delay because the (altered) keybindings haven't yet been loaded, that should not affect the outcome of the calculation.

I think dispatching an untrusted event that is then not canceled is the obvious way to invoke its default behavior, to the extent that Web content should be allowed to do so. There is no security argument for requiring JavaScript to manipulate, say, a textarea directly rather than allowing it to dispatch untrusted events (whether or not those correspond to previously-canceled trusted events) to modify it. There is, however, a correctness argument against it: without precise knowledge of the user's keybindings, it's impossible to know what, say, Ctrl-A should be interpreted to mean.

Even if it weren't for that problem, the fact remains that duplicating the complete editing environment is very complex, requiring hundreds of lines of JavaScript code; by contrast, at least in Firefox, ignoring untrusted events was essentially a one-line change.

If it's too late to revisit this decision, or there are indeed good arguments for it that I'm unaware of, I would like to request that at least an API be added to JavaScript to allow replaying untrusted events (again, to the extent that Web content should be allowed to do so).

@masayuki-nakano
Copy link

masayuki-nakano commented Sep 28, 2017

If untrusted event always triggers default actions, what happens with untrsuted event can be a lot of good hits for fingerprinting. Additionally, it may cause leaking privacy. E.g., if Ctrl+V (paste in most platforms) is allowed, web app can steal any data in the clipboard. E.g., user might copied a password into the clipboard.

Of course there are some default actions which should be performed for backward compatibility. E.g., click event on an <a href> element. So, untrusted events shouldn't trigger any default action unless it is important for backward compatibility. However, if web apps need to kick some default action, the action should be able to be performed with a new API rather than using untrusted event.

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

2 participants