Closed Bug 1745008 Opened 4 years ago Closed 4 years ago

tabs.update with custom scheme URL may replace privileged page with error

Categories

(WebExtensions :: Untriaged, defect)

Firefox 94
defect

Tracking

(firefox95 affected, firefox96 affected, firefox97 affected)

RESOLVED WONTFIX
Tracking Status
firefox95 --- affected
firefox96 --- affected
firefox97 --- affected

People

(Reporter: manikulin, Unassigned)

References

Details

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/94.0

Steps to reproduce:

I am trying to find a way to reliably launch external scheme handler from add-on.

Consider an extension that allows to create a note with current page URL, title, and some more info in an external application, e.g. Org Mode for Emacs https://orgmode.org/manual/Protocols.html Current page may be a privileged one, so e.g. content scripts can not be used, flashing with new temporary tab or window is not optimal from point of view of UX. Handler may be silently swallowed by Firefox if <iframe> is added to background page (Bug #1744018).

tabs.update with custom scheme URI may be used to launch external handler, but such method has a problem with privileged pages when handler is not properly configured at the desktop environment level: current pages switches to error one. For regular pages there is an opposite problem, add-on has not chance to notify user about invalid configuration.

Temporary load the following add-on (I assume, "fox-bug:" scheme is not configured, otherwise change it):

bg-scheme-handler-update.js

"use strict";

var CUSTOM_URI = "fox-bug:test";

async function launchUsingTabsUpdate(tab) {
	if (!tab) {
		tab = await browser.tabs.query({currentWindow: true, active: true});
	}
	const url = CUSTOM_URI + "?time=" + new Date().toISOString();
	console.log("launching %o", url);
	await browser.tabs.update(tab.id, { url });
}

browser.browserAction.onClicked.addListener(
	(_clickData, tab) => launchUsingTabsUpdate(tab));

manifest.json

{
	"manifest_version": 2,
	"name": "Bug: tabs.update and external scheme handler",
	"version": "0.1",
	"browser_action": { "default_title": "Bug: tabs.update and external scheme handler" },
	"background": { "scripts": [ "bg-scheme-handler-update.js" ] }
}

Try to click on browser action button when

  1. Privileged page, e.g. about:preferences is shown in current tab
  2. Current tab displays a regular page

Actual results:

  1. The following error page replaces privileged content:

    The address wasn’t understood

    Firefox doesn’t know how to open this address, because one of the following protocols (fox-bug) isn’t associated with any program or is not allowed in this context.

    You might need to install other software to open this address.

  2. In the console the following error is shown, but it is invisible to extension: "Prevented navigation to “fox-bug:test?time=2021-12-08T15:43:59.197Z” due to an unknown protocol."

Expected results:

  1. I think, current page should be kept even if it is a privileged one.
  2. I do not mind to receive some feedback that configuration is invalid. Though I am unsure that it can be implemented in current API.

P.S. If custom scheme handler is configured than it is launched without "Allow this file to open fox-bug link?" prompt that appears if JS is running in the context of regular web page, it is similar to Bug #1744960

The Bugbug bot thinks this bug should belong to the 'WebExtensions::Untriaged' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.

Product: Firefox → WebExtensions

Hello,

I reproduced the issue on the latest latest Release (95.0/20211129150630), Beta (96.0b3/20211209163454) and Nightly (97.0a1/20211209155024) under Windows 10 x64 and Ubuntu 16.04 LTS.

When clicking the browser action on a priviledged page, the content is replaced with
"The address wasn’t understood/
Firefox doesn’t know how to open this address, because one of the following protocols (fox-bug) isn’t associated with any program or is not allowed in this context./You might need to install other software to open this address."

No warnings/errors are displayed in the console.

When clicking the browser action on a reagular page, the page content remains unchanged but a warning is displayed in the console - "Prevented navigation to “fox-bug:test?time=2021-12-10T08:47:48.002Z” due to an unknown protocol."

Status: UNCONFIRMED → NEW
Ever confirmed: true

Alex, thank you.

A couple of notes that might be related.

  • 2 years ago tabs.update with external protocol handler could switch current tab to loading state (spinning icon on tab label). However currently I can not reproduce such behavior.
  • I had an idea that example add-on is not affected by popup blocker because there is no async calls before tab.update, but in the case of configured handler it is always launched even if await with some delay is added before update call, unlike in Bug #1744018 case.

When I type fox-bug:test in the location bar, Firefox opens a search engine with the given query.

Getting an error page when the extension opens it sounds not unreasonable.

Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → WONTFIX
See Also: → 1744018

(In reply to Rob Wu [:robwu] from comment #4)

When I type fox-bug:test in the location bar, Firefox opens a search engine with the given query.

Getting an error page when the extension opens it sounds not unreasonable.

Rob, if error page sound reasonable for you then why it is not shown when tabs.update is called with unknown scheme on a regular page (not a privileged one).

I realized that I usually have user_pref("keyword.enabled", false); and disabled fixups in my profiles. It is easier for me to use explicit search keywords and to edit precisely what I typed before if I make a mistake. With no such customization third reaction to unknown scheme just increases confusion. It does not affect tabs.update behavior. Fortunately URI with unknown scheme does not leak to search engine.

I believe, the following is far from consistency:

  1. Fallback to search engine if URI is typed by user.
  2. Silent failure for regular page and tabs.update. Current page is still shown
  3. Error page if tabs.update is called from a privileged page, e.g. about:addons
Flags: needinfo?(rob)

(In reply to max from comment #5)

(In reply to Rob Wu [:robwu] from comment #4)

When I type fox-bug:test in the location bar, Firefox opens a search engine with the given query.

Getting an error page when the extension opens it sounds not unreasonable.

Rob, if error page sound reasonable for you then why it is not shown when tabs.update is called with unknown scheme on a regular page (not a privileged one).

I haven't looked for the exact details, but I suspect that it may be due the different ways that privileged pages and content pages are handled. Some privileged pages are hosted directly in the browser process (e.g. about:preferences). Other semi-privileged pages are in a content process, like websites (e.g. about:home). Upon navigating away from a privileged resource to a non-privileged resource (or vice versa), a process switch may occur.

I believe, the following is far from consistency:

  1. Fallback to search engine if URI is typed by user.
  2. Silent failure for regular page and tabs.update. Current page is still shown
  3. Error page if tabs.update is called from a privileged page, e.g. about:addons

I agree that this is not consistent. If anything, the second point would be a bug. But it's not likely going to be fixed in the short term, since we have significantly more bugs to work on that people available. If you are interested in investigating and working on a patch I am willing to support you with answering questions, reviewing patches and/or getting the patch landed in Firefox.

Flags: needinfo?(rob)

(In reply to Rob Wu [:robwu] from comment #6)

(In reply to max from comment #5)

I believe, the following is far from consistency:

  1. Fallback to search engine if URI is typed by user.
  2. Silent failure for regular page and tabs.update. Current page is still shown
  3. Error page if tabs.update is called from a privileged page, e.g. about:addons

I agree that this is not consistent. If anything, the second point would be a bug.

On the other hand silent failure is consistent with behavior of window.location = "fox-bug:test" executed by page or by add-on's content script. (There is even indirect and not really reliable method to detect an error: when focus is passed to external application, the page receives blur event.)

I do not think that users have strong reasons to type URIs for external handler since they are able to launch application directly. Thus I consider fallback to search engine or to error page acceptable. For API methods expected general way to notify about errors is an exception or a specific return value. I admit that in this particular case tabs.update is responsible for changing URL only and processing of new URL is performed in rather different context, so caller can not be notified. However I still consider replacing current page with an error as a worst variant of behavior.

But it's not likely going to be fixed in the short term

My impression is that there is no consistent security model in respect to external scheme handlers and it affects both regular sites and extensions. Browsers tries to protect users from adverse behavior, fingerprinting, etc., but there are ways to bypass some of measures. Noticeable side effect is degraded stability of valid use cases. This bug is one of 4 ones I filed last days for Firefox. I have noticed a couple more issues besides crash-like behavior of Chromium. Maybe the group should be considered as a whole to decide which changes are appropriate for each issue.

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