Open Bug 1813975 Opened 2 years ago Updated 1 year ago

No prompt to choose application for custom link scheme

Categories

(WebExtensions :: Untriaged, defect, P3)

Firefox 109
defect

Tracking

(Not tracked)

UNCONFIRMED

People

(Reporter: manikulin, Unassigned, NeedInfo)

References

Details

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

Steps to reproduce:

Attempt to launch handler for a custom protocol may be silently ignored for add-ons when "always ask" is chosen (Linux, KDE).

  • Configure a custom URI scheme handler in desktop environment.
  • Load some extension that launches the handler using window.location.href = ... in a content script (an example is provided below).
  • Switch to a regular (non-privileged) tab.
  • Invoke add-on action
  • Open settings and in General → Applications change default handler to "Always ask"
  • Switch to a regular page and try to invoke the add-on again
  • ??? Unsure which action triggered the issue: switching between tabs, switching between "Always ask" and default handler and back in settings.
  • Switch to a regular page and try to invoke the add-on again

Actual results:

After some activity "choose application to open the ... link" doorhanger does not appear any more. Regular page console logs "Navigated to..." but the handler is not launched.

The following actions cause reset to default handler in the settings:

  • Set "always ask"
  • Invoke add-on action
  • Close settings, open again and observe default handler as the selected option.

Originally I noticed that 2 profiles behaves differently in respect to a specific URI scheme. One ignores it, another profile is able to display the popup and start the application.

Expected results:

Popup to decide, which handler should be used, works reliably.

I have no idea what I can inspect in browser profiles to figure out what is the difference. Grep and sqlite have not show anything suspicious.

manifest.json

{
	"manifest_version": 2,
	"name": "Scheme handler - location",
	"version": "0.1",
	"browser_action": { "default_title": "Scheme handler-location" },
	"permissions": [ "<all_urls>" ],
	"background": { "scripts": [ "bg-scheme-handler-location.js" ] }
}

bg-scheme-handler-location.js

"use strict";

browser.browserAction.onClicked.addListener(
	(clickData, tab) => browser.tabs.executeScript(tab.id, {
		code: 'window.location.href = "test-protocol:/test"',
		frameId: 0,
		allFrames: false,
	}));

~/.local/share/applications/test-protocol-debug.desktop

[Desktop Entry]
Name=test-protocol debug dialog
Comment=Debugging of test-protocol actions
Exec=zenity --info --title test-protocol --text %u
Type=Application
Terminal=false
MimeType=x-scheme-handler/test-protocol;
update-desktop-database ~/.local/share/applications/

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

Product: Firefox → WebExtensions

Hello max,

I’m from WebExtensions QA and I’m trying to reproduce the issue in order to confirm it.

I would require some assistance on how to configure a custom URI scheme handler as you mentioned in the first step. In this sense, would you be able to provide some more details steps on how to accomplish this, in regards to which files I have to create or add and where, or what I have to modify in existing files etc. ?
Searching the internet for information regarding this has proven futile as I did not find any clear info on how to proceed.

Thank you !

Flags: needinfo?(manikulin)

Alex, I am unaware how to register protocol handler in MS Windows since Linux is my work environment. Particular reason why I decided to register new protocol is to avoid settings hidden somewhere in profiles. Perhaps you may start with irc: as you did in for the Bug #1744960.

For linux ensure that ~/.local/share/applications/ directory exists, if it is missed then create the folder

mkdir --parents ~/.local/share/applications/

Create ~/.local/share/applications/test-protocol-debug.desktop file with content provided in the original report. I assume that zenity dialog tool is available, check it

zenity --info --title test-protocol --text test

and install it otherwise. Run

update-desktop-database ~/.local/share/applications/

and check that

xdg-mime query default x-scheme-handler/test-protocol

reports test-protocol-debug.desktop

I hope, I have not missed any step.

Flags: needinfo?(manikulin)

The bug might be related to bug #1745931, however that case with add-on background page I considered reliably reproducible. I have no idea what determines change in behavior I reported in this issue.

Hello and thank you for the additional info max,

I think I reproduced the issue on the latest Release (109.0.1/20230127170202) and Beta (110.0b9/20230202190127) under Ubuntu 16.04 LTS. I got some trouble with launching Nightly on Linux for some reason and could not test there but will try again soon.

I did the following on Release:

  1. Loaded the extension you provided via about:debugging
  2. Without accessing Settings as I presume the handler is set to “Use test-protocol debug dialog (default)”, I access Wikipedia and invoke the add-on action → nothing happens, no doorhanger or errors/messages in consoles
  3. Accessed Settings and changed handler to “Always ask”, switched to the tab with Wikipedia and invoked the add-on action → nothing happens again
  4. Closed Settings, opened Settings again and noticed the handler was reset to default

I did not see any “choose application to open the … link” doorhanger at all on Release and I tried with 2 different profiles.

On Beta:

  1. Loaded the extension you provided via about:debugging
  2. Without accessing Settings as I presume the handler is set to “Use test-protocol debug dialog (default)”, I access Wikipedia and invoke the add-on action → I get the “Allow the extension Scheme handler – location to open the test protocol link with test-protocol debug dialog?” doorhanger
  3. I choose to “Open Link”
  4. Accessed Settings and changed handler to “Always ask”
  5. Switched to the tab with Wikipedia and invoked the add-on action → got the “choose application” doorhanger
  6. Closed Settings, opened Settings again and the handler was not reset to default
  7. Switched to the tab with Wikipedia and invoked the add-on action → got the “choose application” doorhanger and clicked “Choose Application” (nothing happened)
  8. Refreshed Settings and the handler was reset to default but I do still get the “choose application” doorhanger on Wikipedia when I invoke the add-on.

At this point I’m not sure if I reproduced the issue or not, but the handler does get reset, although it appears to vary on how it happens.

(In reply to Alex Cornestean from comment #5)

under Ubuntu 16.04 LTS. I got some trouble with launching Nightly on Linux for some reason and could not test there

Notice that ubuntu-16.04 release reached its end of support. Current Ubuntu Long Time Support release is 22.04, new one appears every 2 years.

  1. Loaded the extension you provided via about:debugging
  2. Without accessing Settings as I presume the handler is set to “Use test-protocol debug dialog (default)”, I access Wikipedia and invoke the add-on action → nothing happens, no doorhanger or errors/messages in consoles

No "unknown protocol" message in the console for wikipedia is a sign that protocol handler is configured correctly. I would enable "persist logs" though to see at least "navigated to" message.

Previous time at this step I get handler's window. I have tried a new protocol with existing profile and I got neither handler's dialog, nor the doorhanger to choose application. So today behavior is similar to what you observed.

On Beta:

  1. Loaded the extension you provided via about:debugging
  2. Without accessing Settings as I presume the handler is set to “Use test-protocol debug dialog (default)”, I access Wikipedia and invoke the add-on action → I get the “Allow the extension Scheme handler – location to open the test protocol link with test-protocol debug dialog?” doorhanger
  3. I choose to “Open Link”

I have tried beta in a minimal LXC container (no desktop environment in the container, X connection to host). For some reason I got "choose application" button in the doorhanger, not "open link". However it may be result of earlier experiments, namely attempt to test without update-desktop-database and configuring through ~/.config/mimeapps.list.

Did handler's window appear on "open link"?

  1. Switched to the tab with Wikipedia and invoked the add-on action → got the “choose application” doorhanger and clicked “Choose Application” (nothing happened)

I consider "nothing" as success to reproduce the issue since firefox application chooser and zenity dialog window is expected.

At this point I’m not sure if I reproduced the issue or not, but the handler does get reset, although it appears to vary on how it happens.

Just a final sanity check (if you have not tried it before)

xdg-open test-protocol:sanity

should open a dialog window (or perhaps application chooser in the case of Gnome) confirming that protocol handler is configured properly.

Behavior for Gnome and KDE desktop environments may be different in some aspects as well.

Concerning Windows, I have never tried it:
https://stackoverflow.com/questions/80650/how-do-i-register-a-custom-url-protocol-in-windows
Something like cmd.exe or notepad.exe without "%1" argument perhaps may be used as handler command.

I suspect some kind of undefined behavior in this issue, so despite of some difference in your results, I believe that you have managed to reproduce the bug. Thanks.

Since Firefox 110 (which ships to release this week), custom protocols opened by extensions do trigger a prompt (where they previously did not). This is part of bug 1792138.

Max, can you check the behavior in Firefox 110 or later, and confirm whether the behavior is as expected?

See Also: → CVE-2023-25729

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

Since Firefox 110 (which ships to release this week), custom protocols opened by extensions do trigger a prompt (where they previously did not). This is part of bug 1792138.

Max, can you check the behavior in Firefox 110 or later, and confirm whether the behavior is as expected?

I see errors in 110b9, however currently I am not sure that the issue is related to add-ons. To confirm I need more info since currently it looks like undefined behavior. Is there a chance that bug 1792138 will be made public after the release? I have not permissions to read this report.

So what I see with Firefox-110b9, minimal LXC container with Ubuntu-22.04 (no D-BUS connection to host desktop environment).

  • A HTML page is opened as file:/// (open file...)
  • Always ask is chosen for test-protocol in about:preferences
  • In response to click on the temporary add-on entry in new extensions menu
  • Page console: Navigated to test-protocol:/test
  • Doorhanger

Allow the extension Scheme handler - location to open the test-protocol link?

You'll need to choose an application.

[ ] Always allow this extension to open test-protocol links

[Cancel] [Choose _A_pplication]

  • Click on "Choose Application"

  • Handler window is not opened

  • Browser console: NS_ERROR_FILE_NOT_FOUND: Component returned failure code: 0x80520012 (NS_ERROR_FILE_NOT_FOUND) [nsIHandlerInfo.launchWithURI] ContentDispatchChooser.jsm:114

  • I can observe the same behavior if I try any way to launch handler from the JS script from the same page (iframe, window.location)

  • If I change "Always ask" to the handler entry in about:preferences then handler is launched.

  • Behavior is different if I choose mailto: scheme instead of test-protocol:, another doorhanger appears in response to browser action click:

  • Thunderbird Mail
  • Gmail
    https://mail.google.com
  • Choose other Application [Choose...]
  • Always use this application to open mailto links

[Cancel] [_O_pen Link]

and Thunderbird with compose window appears if I click "Open Link".

For Firefox-109 I have a profile where one custom protocol works, another one doesn't, so I am really confused. Has the issue you are writing about been fixed after 110b9?

needinfoing myself to investigate later. The reproduction is complex, and I want to verify the bug in order to decide where the bug should be moved to.

Severity: -- → S4
Flags: needinfo?(rob)
Priority: -- → P3

Rob, I observed completely insane behavior of Firefox-110. Till it is fixed there is no point to discuss more subtle issues, so you can change component to proper one.

All command line options may be stripped after some actions, e.g. I have managed to get several times (command executed in the profile folder)

jq '.schemes["test-protocol"]' handlers.json 
{
  "action": 2,
  "handlers": [
    {
      "name": "test-protocol debug dialog",
      "command": "echo %u"
    }
  ]
}

while originally it was

{
  "action": 2,
  "handlers": [
    {
      "name": "test-protocol debug dialog",
      "command": "echo zenity --info --title test-protocol-debug --text %u"
    }
  ]
}

I added echo after I noticed the following message in terminal from which I started firefox

You must specify a dialog type. See 'zenity --help' for details

Approximate steps to reproduce. Open some regular page and execute in its console location.href = "test-protocol:something" in between of steps related to Firefox

  • Create 2 alternative .desktop files in ~/.local/share/applications/
    test-protocol-debug.desktop
[Desktop Entry]
Name=test-protocol debug dialog
Exec=echo zenity --info --title test-protocol-debug --text %u
Type=Application
Terminal=false
MimeType=x-scheme-handler/test-protocol;

For another one change "debug" to "alt" in the file name and its content.

update-desktop-database ~/.local/share/applications/
  • Start firefox, choose non-default handler (likely "debug" one) in about:preferences
  • Restart firefox, open about:preferences again, open dropdown for test-protocol handler and click on the same entry.

In the terminal from which firefox is started, messages from echo reveal stripped from command options even earlier than handlers.json file is overwritten.

On next start the handlers.json entry persists causing confusing duplicated entry.

See Also: → 1744960

The bug with missed additional arguments may be reproduced with Firefox-102. It is not necessary to restart browser, it is enough to reload the about:preferences page. I have created a script that shows passed options in a dialog window.

  • Remove existing handlers for test-protocol from ~/.local/share/applications and ~/.config/mimeapps.list, run update-desktop-database ~/.local/share/applications/
  • To clean up Firefox state set "Always ask" for test-protocol and remove handlers from "Application details" dialog.
  • jq '.schemes["test-protocol"]' handlers.json should report {"action": 2, "ask": true} without handlers array
  • Setup 2 handlers (.desktop files in ~/.local/share/applications should be created)
    ./test-protocol-dialog -d
    ./test-protocol-dialog -d test-protocol-second "Another test-protocol"
    
  • Set "Another test-protocol" (non-default) handler, evaluate location = "test-protocol:something" and check that `--test-option --" options are passed to the handler
  • Reload the about:preferences page, open drop-down list with test-protocol handlers and click on "Another test-protocol" again.
  • Evaluate location = "test-protocol:something"
    Actual results:
  • "Error! Command line options are lost" message in the test handler.
  • --test -- options are missed before %u in handlers.json

chmod 755 test-protocol-dialog

#!/bin/sh -eu
# Debug Firefox issues with external protocol handler applications.
# Check if command line options specified in the .desktop
# file are passed to the handler.

protocol="test-protocol"
exec_options="--test-option --"

usage()
{
	exe="$0"
	cat <<EOF
To create a .desktop file run
    $exe {-d|--desktop} [DESKTOP_FILE_BASE] [NAME_ENTRY]...
File should be saved in the "applications" subdirectory of
${XDG_DATA_HOME:-~/.local/share}
user folder or system-wide in
${XDG_DATA_DIRS:-/usr/share}
See also: desktop-file-install(1)
EOF
}

desktop_file()
{
	base="$(basename "$0")"
	realpath="$(readlink -e "$0")"
	file_name="${1:-$base}"
	[ "$#" -eq 0 ] || shift
	name="${*:-Debug $protocol handler}"
	case "$file_name" in
		*.desktop)
			;;
		*)
			file_name="$file_name.desktop"
			;;
	esac
	tmpdir="$(mktemp -d "$base.XXXXXX")"
	tmp_desktop="$tmpdir/$file_name"
	# shellcheck disable=SC2016
	cleanup='rm -- "$tmp_desktop" || : ; rmdir -- "$tmpdir"'
	# shellcheck disable=SC2064
	trap "$cleanup" EXIT
	trap "trap - INT ; $cleanup ;"'kill -s INT "$$"' INT
	trap "trap - TERM ; $cleanup ;"'kill -s TERM "$$"' TERM
	cat <<EOF | tee "$tmp_desktop"
[Desktop Entry]
Name=$name
Comment=Debugging of $protocol actions
Categories=Utility
Exec=$realpath $exec_options %u
Type=Application
Terminal=false
MimeType=x-scheme-handler/$protocol
EOF
	if [ 0 = "$(id -u)" ]; then
		desktop-file-install --rebuild-mime-info-cache "$tmp_desktop"
	else
		home_apps="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
		desktop-file-install --dir="$home_apps" --rebuild-mime-info-cache "$tmp_desktop"
	fi
}

check_path() { command -v "$1" 2>/dev/null; }

dialog()
{
	options=''
	style=error
	subject="Error! Command line options are lost"
	help=''
	[ -n "$*" ] || help="
	
$(usage)"
	while [ "$#" -ne 0 ]; do
		case "$1" in
			--)
				options="$options $1"
				shift
				;;
			-*)
				options="$options $1"
				shift
				continue
				;;
		esac
		break
	done
	if [ -n "$options" ]; then
		style=info
		subject='Command line options are passed'
	fi
	title="$protocol: $style"
	message="$subject
$0
Expected options: $exec_options

Actual options: $options
Arguments: $*$help"

	if cmd="$(check_path zenity)"; then
		"$cmd" "--$style" --title "$title" --no-wrap --no-markup --text="$message"
	elif cmd="$(check_path kdialog)"; then
		[ error = "$style" ] || style=msgbox
		"$cmd" --title "$title" "--$style" "$message"
	elif cmd="$(check_path gxmessage)" || cmd="$(check_path xmessage)"; then
		"$cmd" -title "$title" -center "$message"
	elif cmd="$(check_path yad)"; then
		"$(cmd)" --center --wrap --no-markup --title "$title" --text "$message"
	else
		printf "%s: error: no supported dialog app\n%s\n%s\n" \
			"$0" "$title" "$message" 1>&2
		return 1
	fi
}

first="${1:-}"
if [ "-d" = "$first" ] || [ "--desktop" = "$first" ]; then
	shift
	desktop_file "$@"
else
	dialog "$@"
fi
You need to log in before you can comment on or make changes to this bug.