Open Bug 1392624 Opened 3 years ago Updated 4 months ago

Extension UI surface (browserAction, pageAction, sidebar) cannot be opened from non-extension pages

Categories

(WebExtensions :: Frontend, enhancement, P5)

56 Branch
enhancement

Tracking

(Not tracked)

People

(Reporter: robwu, Unassigned)

References

Details

Attachments

(1 file)

Bug 1341126 added the ability to open extension popups/sidebars, but guarded behind a requireUserInput flag.

The requireUserInput flag is currently set for the following APIs:
- permissions.request
- downloads.open
- browserAction.openPopup
- pageAction.openPopup
- sidebarAction.open
- sidebarAction.close

These APIs are only available in privileged extension contexts, i.e. moz-extension documents where the top-level frame is also the same moz-extension origin.
Since a background page cannot generate a user gesture, the only pages where requireUserInput can be used are:
- Extension popup or sidebar.
- Extension in tab.


The following are also clear instances of user input, yet they do not set the user input flag:
- browserAction.onClicked
- pageAction.onClicked
- contextMenus.onCommand

Further, an extension can register an input listener in a content script, and want to invoke some functionality in the background page based on the input. For example:
- Request optional permissions in response to a trusted click event.
- Open a pageAction popup when the user initiates input (so that extensions can open a safe UI surface to request input, unspoofable by a web page).

In both of the last examples, there is a risk of abuse. However, bad extensions can also open many popups without any limitations, so offering the ability to call openPopup in response to user input is not that bad.


I believe that the APIs that result in UI (permissions.request, *.openPopup, sidebarAction.*) can safely be made available to a user gesture from a content script.
The downloads.open API allows extensions to launch external software, so that should probably not be available via a content script input event.


The feature request is thus:
- Set the requireUserInput flag in the extension events that indicate user input (onClicked/onCommand).
- Allow user input to be transferred via runtime.sendMessage to runtime.onMessage.
  It is probably good to require an explicit option in the runtime.sendMessage event, so that extensions don't inadvertently trust runtime.sendMessage events from badly coded content scripts in untrusted pages.

Internally, there should be a distinction between direct user input and transferred user input, because otherwise an extension can artificially inflate the lifetime of the user gesture by ping-ponging with runtime.sendMessage and runtime.onMessage.


FWIW, Chrome allows user gestures to be transferred in extension messages (sendMessage->onMessage), and even from callback to callback: https://crbug.com/361116
Example extension:

1. Unpack the zip file to a directory, and load the directory as an extension via about:debugging.
2. Open a web page, e.g. example.com
3. Click in the page.

Expected result:
- Extension UI appears (the extension popup shows up in Firefox 57+ after bug 1341126; or a permission prompt appears)
- Set the requireUserInput flag in the extension events that indicate user input (onClicked/onCommand).

I'm not clear what you're trying to get here.  onClicked only works if there is no popup, so openPopup wouldn't work anyway.

- Allow user input to be transferred via runtime.sendMessage to runtime.onMessage.
  It is probably good to require an explicit option in the runtime.sendMessage event, so that extensions don't inadvertently trust runtime.sendMessage events from badly coded content scripts in untrusted pages.

This seems more complicated than just allowing content scripts to call openPopup.

Lets see what aswan thinks on this as well.
Flags: needinfo?(aswan)
(In reply to Shane Caraveo (:mixedpuppy) from comment #2)
> - Set the requireUserInput flag in the extension events that indicate user
> input (onClicked/onCommand).
> 
> I'm not clear what you're trying to get here.  onClicked only works if there
> is no popup, so openPopup wouldn't work anyway.

Firefox allows a page_action and a browser_action to be declared.
In IRC :aswan said that this specific bug (with onClicked/... not running with user input) has been fixed in 56 - by bug  1369577.


> - Allow user input to be transferred via runtime.sendMessage to
> runtime.onMessage.
>   It is probably good to require an explicit option in the
> runtime.sendMessage event, so that extensions don't inadvertently trust
> runtime.sendMessage events from badly coded content scripts in untrusted
> pages.
> 
> This seems more complicated than just allowing content scripts to call
> openPopup.
> 
> Lets see what aswan thinks on this as well.

"allowing content scripts to call openPopup" means exposing privileged methods to content scripts.
And openPopup is just one example, there are other APIs (such as permissions.request, see report).
I agree that exposing openPopup() to content scripts would be marginally easier than allowing the isHandlingUserInput status to be propagated but I also agree with Rob that it is undesirable.  Off the top of my head, I think that propagating isHandlingUserInput should be straightforward.  The sticky bit in the original patch for bug 1369577 was finding the right <browser> element for a permission prompt and I assume openPopup() also needs to know which <browser> to open the popup in.  But that should be easy to get in this case.
Flags: needinfo?(aswan)
Priority: -- → P5
Duplicate of this bug: 1397658
as stated in bug 1397658, i'd also like to see the isHandlingUserInput status stay valid on background pages which perform the permission check within a chrome.runtime.onMessage listener, triggered by browser action popups doing a chrome.runtime.sendMessage.
Duplicate of this bug: 1433167
(In reply to Shane Caraveo (:mixedpuppy) from comment #2)
> - Set the requireUserInput flag in the extension events that indicate user
> input (onClicked/onCommand).
> 
> I'm not clear what you're trying to get here.  onClicked only works if there
> is no popup, so openPopup wouldn't work anyway.

Which I've discovered I was wrong about, it works perfectly well.
Duplicate of this bug: 1443285
Product: Toolkit → WebExtensions

1Password would love to use browserAction.openPopup in our content script. We would also find it helpful to open the popup in response to notifications.onClicked or onButtonClicked which I believe is also a clear instance of user input. Any word on this issue moving forward?

(In reply to beyer from comment #10)

We would also find it helpful to open the popup in response to notifications.onClicked or onButtonClicked which I believe is also a clear instance of user input. Any word on this issue moving forward?

Treating notification clicks as user input is tracked in bug 1402612.
(Firefox only supports notifications.onClicked, not onButtonClicked, by the way.)

You need to log in before you can comment on or make changes to this bug.