Intent to Ship: Do not perform default action on un-trusted events

290 views
Skip to first unread message

Dave Tapuska

unread,
May 10, 2016, 5:18:49 PM5/10/16
to blink-dev
dtap...@chromium.org https://www.w3.org/TR/uievents/#trusted-events According to the UI Events specification un-trusted events should not invoke the default action. 'click' is the only event that is a legacy permitted case. The isTrusted support was added in https://www.chromestatus.com/features/6461137440735232 which identifies trusted events from un-trusted events. We wish to prevent synthetic events from executing the default action.

This feature has been implemented behind a runtime flag for some time the goal is to move it from a disabled runtime flag to a stable runtime flag.
Other vendors are compliant with the spec and we wish to be more inter-operable with this request. There are a number of things that javascript can do to steal focus from the user by allowing synthetic events to execute the default action so there are security benefits with making this change. Issues such as 160471 and 423975 as solved by implementing this feature.
Firefox: No public signals Edge: No public signals Safari: No public signals Web developers: No signals We do believe there are some sites taking advantage of our dispatching of un-trusted events. We do know that some sites will actively cause a select to open by injecting a synthetic mouse event. Initially I proposed https://discourse.wicg.io/t/htmlselectelement-add-ability-to-show-option-list-programmatically/1035 to address the potential concerns of developers using the current feature. However since there are issues with iframe's distracting the user input with this feature. I believe it is in the user's best interest to disallow the execution of un-trusted events. Firefox and Edge both do not allow this behaviour.

The discourse hasn't had many requests other than when I first initially proposed it and no comments since identifying I may not pursue it. I want to propose we make this change now for M52. If there is enough feedback from the community once the change is made we can re-evaluate the discourse.
None
Yes https://crbug.com/520519 https://www.chromestatus.com/features/5718803933560832

Rick Byers

unread,
May 10, 2016, 6:04:02 PM5/10/16
to Dave Tapuska, blink-dev, Bogdan Brinza
On Tue, May 10, 2016 at 2:18 PM, Dave Tapuska <dtap...@chromium.org> wrote:
dtap...@chromium.org https://www.w3.org/TR/uievents/#trusted-events According to the UI Events specification un-trusted events should not invoke the default action. 'click' is the only event that is a legacy permitted case. The isTrusted support was added in https://www.chromestatus.com/features/6461137440735232 which identifies trusted events from un-trusted events. We wish to prevent synthetic events from executing the default action.

This feature has been implemented behind a runtime flag for some time the goal is to move it from a disabled runtime flag to a stable runtime flag.
Other vendors are compliant with the spec and we wish to be more inter-operable with this request. There are a number of things that javascript can do to steal focus from the user by allowing synthetic events to execute the default action so there are security benefits with making this change. Issues such as 160471 and 423975 as solved by implementing this feature.
Firefox: No public signals Edge: No public signals

Firefox and Edge already comply with the spec here, right?  Then I'd consider their support as "shipping". 

Safari: No public signals Web developers: No signals We do believe there are some sites taking advantage of our dispatching of un-trusted events. We do know that some sites will actively cause a select to open by injecting a synthetic mouse event. Initially I proposed https://discourse.wicg.io/t/htmlselectelement-add-ability-to-show-option-list-programmatically/1035 to address the potential concerns of developers using the current feature. However since there are issues with iframe's distracting the user input with this feature. I believe it is in the user's best interest to disallow the execution of un-trusted events. Firefox and Edge both do not allow this behaviour.

I agree that the annoyance (and security) issues with allowing JavaScript to open select boxes mean we should just move to match other browsers here.  In all major browsers, select boxes are are system UI - they capture input across all frames and can draw UI outside their containing document's bounds.  This means they unfortunately must be subject to some restrictions.

The discourse hasn't had many requests other than when I first initially proposed it and no comments since identifying I may not pursue it. I want to propose we make this change now for M52. If there is enough feedback from the community once the change is made we can re-evaluate the discourse.

We know this is going to affect some real sites (IIRC there's a mozilla bug somewhere about some sites that works in Chrome/Safari but not Firefox for this reason, and I know Edge folks have approached us about this due to real web compat issues + bbrinza).  So I think we probably need a UseCounter and deprecation message before breaking these sites, eh?

Other than opening a select box, are you aware of any other scenarios where web developers are relying on this?  I guess there's no easy way to UseCount all default actions that occur today as a result of untrusted events, right?  Should be easy / meaningful to explicitly count/deprecate untrusted mousedown events on select elements though, right?

Dave Tapuska

unread,
May 10, 2016, 8:21:41 PM5/10/16
to Rick Byers, blink-dev, Bogdan Brinza
I can certainly add a use counter. I'm not certain why we can't do this for all events. Am I missing something?


This code (and like 235) could be modified so that a use counter is incremented when a default action is performed on an untrusted event. But we probably don't want to count click events because we know we will keep that behaviour.

How about I add the use counter for M52 and remove this in M53?

dave.

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Rick Byers

unread,
May 10, 2016, 8:33:08 PM5/10/16
to Dave Tapuska, blink-dev, Bogdan Brinza
On Tue, May 10, 2016 at 5:21 PM, Dave Tapuska <dtap...@google.com> wrote:
I can certainly add a use counter. I'm not certain why we can't do this for all events. Am I missing something?


This code (and like 235) could be modified so that a use counter is incremented when a default action is performed on an untrusted event. But we probably don't want to count click events because we know we will keep that behaviour.

My concern is that it's not sufficient to count how many default handlers we're running for untrusted events.  I think this will just tell us how common dispatching untrusted events are, which isn't terribly relevant (we know it's common, but most such uses won't be impacted by the change here).  What we'd ideally count is how often we run a default handler that has some observable effect.  You could probably do that by instrumenting all the implementations of Node::defaultEventHandler (and the functions they call), but last I looked there was quite a wide variety of code here - kind of hard to fully understand the impact.  But I guess that's the central question in this intent, so maybe it's worth doing?

Then again, I believe we know that the <select> case is the only one that Edge had a web compat issue with in practice (though I could be mis-remembering).  So maybe deprecating that is sufficient.

How about I add the use counter for M52 and remove this in M53?

Use counter + deprecation warning in M52, with a plan to remove in M53 (assuming the usecounter data looks reasonable) SGTM. 

TAMURA, Kent

unread,
May 10, 2016, 8:54:57 PM5/10/16
to Rick Byers, Dave Tapuska, blink-dev, Bogdan Brinza
Probably adding code like "if this is not a click event and not a trusted event, UseCounter::count()" to Event::setDefaultHandled() is enough.

--
TAMURA Kent
Software Engineer, Google


Dave Tapuska

unread,
May 10, 2016, 8:58:13 PM5/10/16
to TAMURA, Kent, Rick Byers, blink-dev, Bogdan Brinza
Looking at the code I do see something problematic with https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp&sq=package:chromium&rcl=1462908088&l=334 Seems events to plugins are primary dispatched via the default event handler code.

But nonetheless this would be problematic how this code is currently implemented.

I will withdraw my request to ship now; and turn this into an intent to implement.

dave.

Elliott Sprehn

unread,
May 10, 2016, 9:49:17 PM5/10/16
to David Tapuska, Kent TAMURA, Bogdan Brinza, blink-dev, Rick Byers

I think this breaks the undo support in the auto complete widget used by Rietveld.

https://github.com/esprehn/chromium-codereview/blob/master/ui/components/cr-user-autocomplete.html

I'm not sure if that works in Firefox today, but I tried many things to get it to work and this was the only way in Chrome. I don't think we should change this unless there's an alternative that isn't rebuild text input yourself.

Dave Tapuska

unread,
May 11, 2016, 12:06:50 PM5/11/16
to Elliott Sprehn, Kent TAMURA, Bogdan Brinza, blink-dev, Rick Byers
Is there a reason why you chose to dispatch a text input event vs calling execCommand directly? execCommand('insertText',...) should replace the selection text from my understanding.

dave.

PhistucK

unread,
May 11, 2016, 12:11:51 PM5/11/16
to Elliott Sprehn, David Tapuska, Kent TAMURA, Bogdan Brinza, blink-dev, Rick Byers
Perhaps undo should accommodate script-entered changes as well?
There used to be an UndoManager (or something) proposal, but I think it has not taken off.

Though I see that execCommand works -

Ugly, yes - but works. :)


PhistucK

Ashley Gullen

unread,
May 11, 2016, 1:46:20 PM5/11/16
to Dave Tapuska, blink-dev
Another case where you must dispatch events because there is no API is to invoke a download with the a[download] attribute. Currently the only way to start a download from JS is create a temporary a element, set its download attribute, and dispatch a mouse event to it. Perhaps there should be a navigator.download() method or equivalent to cover this case so it doesn't rely on having to dispatch untrusted events?


--

PhistucK

unread,
May 11, 2016, 1:52:28 PM5/11/16
to Ashley Gullen, Dave Tapuska, blink-dev
Why do you need to dispatch an event? I think element.click() should work. Besides, this intent will not break your case, because you dispatch "click" events which are excluded from this policy anyway.


PhistucK

Ashley Gullen

unread,
May 11, 2016, 1:54:03 PM5/11/16
to PhistucK, Dave Tapuska, blink-dev
Oh, I didn't know click() worked. Never mind then!

Jochen Eisinger

unread,
May 11, 2016, 4:39:21 PM5/11/16
to Dave Tapuska, blink-dev
To me this looks more like an intent to deprecate & remove than an intent to ship?

Dave Tapuska

unread,
May 11, 2016, 4:44:43 PM5/11/16
to Jochen Eisinger, blink-dev
Can we treat it as an intent to deprecate based on the discussion?

I will send out a separate intent to remove when we have some uma data.

dave.

Jochen Eisinger

unread,
May 11, 2016, 4:47:29 PM5/11/16
to Dave Tapuska, blink-dev
sgtm!

Dave Tapuska

unread,
May 17, 2016, 11:07:46 AM5/17/16
to Jochen Eisinger, blink-dev
Can I have a consensus to move forward on this action or not?

It has been changed to an Intent to Deprecate. In M52 with removal in M53.

dave.

Rick Byers

unread,
May 17, 2016, 11:37:51 AM5/17/16
to Dave Tapuska, Jochen Eisinger, blink-dev
Deprecation sounds good to me and doesn't require API owner approval.

Let's discuss removal once you have some UMA data on the potential impact.


Malte Ubl

unread,
Jun 23, 2016, 9:58:17 AM6/23/16
to Rick Byers, Dave Tapuska, Jochen Eisinger, blink-dev
Is there an update on shipping this? Could this possibly be just shipped without deprecation cycle for sandboxed iframes?

Dave Tapuska

unread,
Jun 23, 2016, 10:01:11 AM6/23/16
to Malte Ubl, Rick Byers, Jochen Eisinger, blink-dev
How timely is your email....

Elliott Sprehn

unread,
Aug 3, 2016, 1:42:00 AM8/3/16
to Rick Byers, Dave Tapuska, Jochen Eisinger, blink-dev
Fwiw removing this did break the autocomplete in Chrome's codereview tool as I said:

and execCommand doesn't appear to work on input elements in Firefox, so this requires even worse hacks based on the UA string:

See:

though finding any docs on execCommand or using it with input elements proved super hard.

Also see other people using dispatchEvent here, we probably broke all of them:


On Tue, May 17, 2016 at 8:37 AM, Rick Byers <rby...@chromium.org> wrote:

PhistucK

unread,
Aug 3, 2016, 11:49:34 AM8/3/16
to Elliott Sprehn, Rick Byers, Dave Tapuska, Jochen Eisinger, blink-dev
Wait, but Firefox does not fire the default action for non-click events, if I remember correctly. I guess the underlying issue (in your case) here is that Chrome does not add value changes triggered by programmatically dispatched input events to the undo stack, or am I missing something?

(This seems like a bit of a gray area, since execCommand does trigger a "default action" even though it was not the real event that the user fired)

Also, Blink will probably stop applying execCommand to <input> and <textarea> soon, so your check will fail (but I guess you should have not used browser detection in the first place :P).


PhistucK

PhistucK

unread,
Aug 3, 2016, 12:04:25 PM8/3/16
to Elliott Sprehn, Rick Byers, Dave Tapuska, Jochen Eisinger, blink-dev
I think this specific default action (adding to the undo stack) should just be whitelisted. Does anyone think that programmatically modifying the undo stack is harmful? And if so, why is it fine for execCommand to do it?

What does the specification say about the undo stack in relation to default actions?


PhistucK

Elliott Sprehn

unread,
Aug 3, 2016, 12:18:41 PM8/3/16
to PhistucK, Jochen Eisinger, Dave Tapuska, blink-dev, Rick Byers, yo...@chromium.org, Ojan Vafai

I don't think it's acceptable to stop running execCommand against input and textarea. That completely breaks inserting text with the undo stack and was explicitly given as the workaround and a justification for this change.

So we need to either revert this default actions patch for textInput events or not change execCommand. Doing both breaks the web and leaves no workaround.

PhistucK

unread,
Aug 3, 2016, 12:22:57 PM8/3/16
to Elliott Sprehn, Jochen Eisinger, Dave Tapuska, blink-dev, Rick Byers, Yoshifumi Inoue, Ojan Vafai
Yep, I agree that input events (textInput or the standard input) should just trigger undo stack modification.


PhistucK

gong...@gmail.com

unread,
Aug 7, 2016, 6:13:48 AM8/7/16
to blink-dev, dtap...@chromium.org
I agree that "execCommand" against input / textarea should be retained.

We indeed needs "void open();" and "void close();" for <select> if untrusted mousedown events are to be ignored.

BTW, is there any method for an Chrome extension like Vimium to create a "trusted" event programmatically by any special API?
This extension is designed for users to quickly operate the page with only a keyboard (and few mouse operations) ?

在 2016年5月11日星期三 UTC+8上午5:18:49,Dave Tapuska写道:

Dave Tapuska

unread,
Aug 11, 2016, 11:53:13 AM8/11/16
to gong...@gmail.com, blink-dev
In terms of the open, close etc. It was discussed that because of the really low usage of executing the default action for untrusted events. If people wanted this they could build their own custom select with shadow dom. That would give an inter-operable solution across all browsers.

We really should measure the usage of execCommand on input fields. I agree that there isn't a good work around otherwise and suggest leaving it and specing it for inter-op.

In terms of extensions there are a few APIs that already let you generate trusted events from extensions. See https://developer.chrome.com/extensions/input_ime#method-sendKeyEvents and https://developer.chrome.com/extensions/debugger#method-sendCommand

dave.




--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.

jklap...@gmail.com

unread,
Sep 22, 2016, 1:44:55 PM9/22/16
to blink-dev, ash...@scirra.com, dtap...@chromium.org
Unless I'm mistaken, element.click() does not work when the element is an anchor (which is exactly the case she is describing here).

In our particular case we were using initMouseEvent and it is broken in chrome v53 (somewhat as expected after learning about this):

var blob = new Blob([data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute('href', url);
// Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
link.setAttribute("download", filename);
 
// Simulate clicking the download link
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click'truetrue, window, 1, 0, 0, 0, 0, falsefalsefalsefalse, 0, null);
link.dispatchEvent(event);

I have attempted other methods:

var downloadLink = angular.element('<a></a>');//create a new  <a> tag element
downloadLink.attr('href', url);
downloadLink.attr('download', filename);
downloadLink.attr('target''_self');
downloadLink[0].click();//call click function

I've also tried switching to filesaver.js (https://github.com/eligrey/FileSaver.js/blob/master/FileSaver.js) which uses the MouseEvent constructor. None of these methods cause the download dialogue to open as they did previously (chrome <53).

We've had to switch to IE temporarily to demo the file download functionality but I'm unsure how we are going to be able to continue.

Dave Tapuska

unread,
Sep 22, 2016, 3:42:25 PM9/22/16
to jklap...@gmail.com, blink-dev, ash...@scirra.com
The following example which follows an href works for me:
Individual Example: http://jsbin.com/gadodeq (warning it follows to the bbc)

And here is an example with stimulating a download (and it downloads an image representing the first day of fall).
Individual Example: http://output.jsbin.com/kolape

Something else must be going on in your example. Can you prepare a jsbin? Feel free to log and issue and we can discuss on that so we don't spam the list.

dave.

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.

Reply all
Reply to author
Forward
0 new messages