-
-
Notifications
You must be signed in to change notification settings - Fork 207
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
NativeMessaging portal for sandboxed browsers #655
Comments
How would the issues raised here be dealt with? https://bugzilla.mozilla.org/show_bug.cgi?id=1621763#c2 |
This proposal seems like it's intended to solve the "Interaction" point in that comment, but not the "Discovery" point: if the browser wants to enumerate all the native messaging modules on the host, it cannot. Do browsers need to be able to do that? (I could see this going either way, depending whether communication with a native messaging module is initiated by the extension/webapp or by the browser.) |
Are Firefox native messaging modules and Chrome native messaging modules interchangeable? Would there ever be a situation in which a user wants to expose only a subset of native messaging modules to one of the browsers? Are extensions and origins interchangeable? What's the security model for allowed extensions and origins? It seems to me that in this proposal, we're implicitly trusting the browser to tell us the correct extension/origin from which it got the request (components outside the browser have no way to know whether we can believe it) - which means that filtering could equally well be done by the browser itself, as it is in non-Flatpak, non-Snap browsers, as long as the browsers have a way to read the extension's list of allowed extensions and origins themselves. |
From the documentation you linked, it seems the answer is no: each browser has its own browser-specific search path for manifests, and it's not obvious how we would correlate those with Flatpak and Snap app-IDs (except by hard-coding). |
The discovery problem is a problem of the x-d-p. If an application provides a NativeMessaging app manifest on the host the portal will discover it (if it knows about all the well-known directories for each browser… urgh). If The application is in a sandbox itself and the app manifest has a path in that sandbox the portal won't be able to call it. I don't think the browser needs to know about all existing app manifest but only react when an extension requests access to one. How the "Interaction" problem is solved is not really clear to me. If the NativeMessaging app is in flatpak the path in the manifest is still a host path.
Since the manifests are somewhere on the host and the browsers are in a sandbox they don't see the manifest. We could just as well return the allowed extensions and origins instead of checking them for the browser. Deciding if an app should be able to access a specific or all NativeMessaging endpoints on the other hand is a really hard problem. Should we hardcore firefox and chrome? Let the user decide? What data can the user make a decision on? E.g. if a keyring application can be talked to by any application through NativeMessaging that would be really bad. |
Being a dedicated portal for native messaging, it doesn't sound too bad that it has to know of a list of well-known directories where to search for manifests. I haven't given much thought to endpoints packaged as flatpaks/snaps themselves, but that's an interesting prospect indeed. It sounds like the portal would need some additional logic to know where to look for them, and to invoke the right executable.
Agreed, the browser doesn't need to discover all manifests, only to delegate to the portal when an extension requires talking to a given origin.
Yes, that's the point: the browser requests talking to a given extension/origin, and the portal handles locating the corresponding endpoint and initiating communication with it.
Supposedly, the portal would mediate that by informing the user which application (browser or not) is trying to launch which endpoint, and requesting permission (which might then be cached to avoid subsequent blocking dialogs). I am not familiar with the internals of x-d-p (yet), hopefully this makes sense? |
How would this look to a user? We should try to avoid situations where we pop up a dialog that, to a non-technical user, might as well say
|
This seems like something where it might be a lesser evil to have static permissions (in the Flatpak metadata or Snap's equivalent, similar to how access to e.g. X11 is handled), so that Firefox can contact native messaging providers that were found in Firefox directories, Chromium (and Chrome and ungoogled-Chromium) can contact native messaging providers that were found in Chromium directories, and random non-browser apps can't contact any native messaging providers. |
Yes, that sounds reasonable. |
That would work but it's far from ideal. Taking a step back, what we really want is for applications to communicate with each other freely through dbus. The application providing a bus should then have a policy, possibly even ask the user what to do, to decide what another app is allowed to do. That only works if apps can authenticate each other and requires something like o.fd.DBus.GetConnectionCredentials. With such a system in place there could be a new NativeMessaging scheme which has a strong security model which works with sandboxed and host apps on either side. As a stop-gap solution the static permissions might be reasonable though. |
We could certainly work with a static permission, similar to how the network connectivity portal decides whether to answer requests from the client. On the snapd side, we've already got a "browser-support" permission that might be an appropriate proxy for this permission (although it is also used by some Electron apps), which we could expose to x-d-p. As far as separating out Chrome vs. Firefox native messaging hosts, I'd originally hoped we could mostly rely on the different format for extension IDs to pick the right executables. As a quick example, here are the two json files for the native messaging host for gnome-shell's browser extension: For Firefox: {
"name": "org.gnome.chrome_gnome_shell",
"description": "Native connector for extensions.gnome.org",
"path": "/usr/bin/chrome-gnome-shell",
"type": "stdio",
"allowed_extensions": [
"[email protected]"
]
} and for Chrome: {
"name": "org.gnome.chrome_gnome_shell",
"description": "Native connector for extensions.gnome.org",
"path": "/usr/bin/chrome-gnome-shell",
"type": "stdio",
"allowed_origins": [
"chrome-extension://gphhapmejobijbbhgpjhcjognlahblep/",
"chrome-extension://olkooankbfblcebocnkjganpdmflbnbk/"
]
} We could do separate portal APIs for Firefox style hosts (match on |
Based on the discussion here, there are two main deficiencies in the initial
For (1), the existing For (2), while we might not show one if we go for the static permission route, it might still be worth while designing the API to allow it. So we'd probably want an API that returns a This would give an API something like: <!-- Create a session object representing an instance of a native messaging host. -->
<method name="CreateSession">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="handle" direction="out"/>
</method>
<!-- Start the named native messaging host. Returns a Request object that will signal success if the native messaging server could be started -->
<method name="Start">
<arg type="o" name="session_handle" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="s" name="extensionOrOrigin" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="o" name="handle" direction="out"/>
</method>
<!-- Get the stdin/stdout file descriptors for the session. Will fail if session has not been successfully started -->
<method name="GetPipes">
<arg type="o" name="session_handle" direction="in"/>
<arg type="h" name="stdin" direction="out"/>
<arg type="h" name="stdout" direction="out"/>
</method> As with other session based APIs, sessions will automatically get killed if the D-Bus peer that created them disconnects from the bus. |
Thanks for working on this @jhenstridge - I was looking at it earlier this month to see if we could get the Chrome GNOME extension working on Endless OS and someone pointed me towards this ticket. Is the intention that the static permission is basically all or nothing? Ie with the permission, a browsers are able to access any native message host, and the browser is trusted to whatever internal sandboxing/ACLs to restrict that to the right sites, and the system vendor/admin/user outside the sandbox is in control of which native extensions they want to take that chance with? (The reason I ask is that I was about to point out that a static permission that enabled access per native messaging host would be relatively useless, as it would require the packaging for each browser to know ahead of time which extension + host combinations the browser user might want to use. Or, a mechanism for the OS to tell Flatpak to give access all of these available hosts to all of the browsers, but that becomes essentially equivalent to "let any browser access any messaging host".) I think a request to the user is not as bad as first thought, because the OS can take care of illustrating to the user what is being accessed, ideally making use of metadata about the messaging hosts and which package/whatever they come from. The information we gain here, which is not otherwise accessible, is confirmation from the user that the access is happening when they are trying to use it, rather than maliciously/unexpectedly in the background when the user thinks something else is going on. So you could have a dialog like:
A further complication which I think is worth considering, even if we decide to implement/solve it later, is that we have >0 examples of apps themselves which would ideally be able to offer native messaging hosts. KeePassX has a Flatpak and its native messaging stuff doesn't really work unless you do some weird gymnastics at the moment. flathub/org.keepassxc.KeePassXC#29 Perhaps this becomes, at least for Flatpaks, an export mechanism similar to search providers where the export is present but requires additional user consent/action to have the export activated. This might argue in favour of the user consent mechanism because the portal could see the message host exported from the Flatpak, and check whether the user wants them to be patched together in this way. |
The suggestion about static permissions was from #655 (comment). If we can come up with an understandable wording for the access control dialog, then we could certainly include that. With the API proposal above, I wanted to make sure we didn't back ourselves into the corner of never being able to show such a dialog. As far as sandboxed native messaging servers go, I see that as a separate problem that may be best solved in the individual confinement systems. If flatpak or snapd learned how to write out a native messaging JSON metadata file in a way that a traditionally packaged browser can find, then this proposed portal would also make that server available to confined web browsers too. The important part here would be to ensure that the command in the JSON file causes the server to be invoked with the appropriate sandboxing. I don't think KeepassXC's current approach of writing out the JSON metadata file at runtime is something we'd really want to support, since it would effectively be a sandbox escape vulnerability. But if the package maintainer could ask flatpak/snapd to create the metadata file on its behalf, then it wouldn't matter that the one KeepassXC writes out is ignored. |
Sounds good - in Flatpak land exported files such as .desktop, .service, etc files are rewritten so that the Exec= line includes the appropriate |
That's essentially how snaps are exposed to the system too. One wrinkle though is that the specs for Firefox/Chromium only let you specify the executable for the native messaging server: not its arguments. So you'd probably need to also write out a shell script that does |
IMO the suggested prompt is exactly what we try to avoid: there isn't any way for a normal user to judge if it should be allowed or not. If we go for static permission I don't see the point of this. It would also be good if we didn't have to modify flatpak. Finding all NativeMessaging connectors could probably be done by searching a specific directory on the host and a specific directory for every flatpak (e.g. ~/.var/app/$APPID/config/.NativeMessaging) and snap which has the additional requirement that the name in the NativeMessaging metadata is a prefix of the $APPID. NativeMessaging hosts from a flatpak would then be started with This already is a hack and in the long term I would love to replace this with just dbus but until then it would be neat if we can contain it in the portal as much as possible. |
If it's possible to be specific about what's being accessed, then the user can decide, e.g.:
|
If the connector is a flatpak we could get reliable names but what does accessing KeePassXC mean? How can I judge that Firefox is not doing anything horrible with KeePass? What information do I gain by that message when I already installed KeePass and the Firefox extension? |
The user is even prompted on choosing / allowing an app / system handler to open their supported file types / links. This kind of prompts is not unprecedented (even if some of the prompts are from Firefox itself). As a user you wouldn't expect any app to be able to access any other app, especially with sandboxing on mobile OS'es nowadays. Of course, reality vs expectation, but my point is the user can understand these prompts if they're worded correctly. |
Hi, just pinging this. I just noticed that the respective Firefox bug report was changed from "unconfirmed" to open today, after two years. I'd love to use the flatpak instead of manually downloading the binary package from Getmozilla.org and manually integrating it into the system. Flatpak has the distinct advantage of being both well integrated into the system and up-to-date at the same time. But of course, since native messaging doesn't work in flatpak, some of the extensions I absolutely need, such as keepassxc-browser are broken, and that's why I am forced to using the tar.bz2 instead of the flatpak anyway. Since I am not a programmer, I have nothing to contribute here, just nagging. But it seems, that indeed, this should be addressed on the flatpak side. I guess there is little that packagers of Firefox etc can do to work around this. |
From discussion at the Ubuntu Summit:
Post merge:
These changes were not included in the PR because we had not previously locked down the D-Bus API. |
Hi, sorry to bother, but I just want to ask if this issue is related to why I can't get this extension to work with Flatpaks. |
Yes. That extension uses NativeMessaging, which currently doesn't work with flatpak. |
I use Ubuntu with SNAP. The strange part is, for KeePassXC I had to install flatpak and used Flatpak to activate Native Messaging to my SNAP Firefox.
|
any news when native messaging may work in flatpak browsers? |
Here is a partial solution: aclap-dev/vdhcoapp#91 (comment) |
@cheako the workaround have been known for a while -- I've commented something similar in flathub/org.freedownloadmanager.Manager#1 (comment) though not using a This issue is for a proper solution that doesn't rely on manually poking holes in the sandbox and is handled dynamically, automatically, and securely through a portal. You can track the progress in PR #705. |
Any progress in this issue? I've just started using Firefox flatpak on Wayland and discovered that it is impossible to use keepassxc-browser (with xorg disabled in Flatseal).
keepassxreboot/keepassxc-browser#1875 (comment) I also found this workaround but as I am basic-skills Linux user I have no idea how to compile keepassxc-proxy-rust. Anyway, looks like there is no (easy) way to use any offline password manager with flatpak at present. This kinf of limits the joy of using flatpaks. |
@omega3 one "easy" "way" I use is to give up on browser integration and use a hotkey to open keepassxc. You still have to manually find and copy the password but realistically it only takes a few seconds at most if you don't use mouse except to focus the password field in the end. Works best with "hide keepassxc to system tray on close" setting. Also it works with other apps too |
@omega3 Here is a guide how to set it up: keepassxreboot/keepassxc-browser#1631 (comment) |
Does this portal has to be updated to also work with Thunderbird? The code base for native messaging is the same as for Firefox. Example of one mail extension that uses native messaging is https://github.com/kkapsner/keepassxc-mail/ (see kkapsner/keepassxc-mail#95 for the related issue) |
Sorry for nagging, but this seems to be an essential capability for a lot of software. Currently I struggle with Zotero, Libreoffice and Firefox. They need to communicate with each other but none of them do |
Zotero Flatpak can communicate with LibreOffice Flatpak. It doesn't need native messaging. @secretmango In LibreOffice go to extensions and add the extension. But yes, Zotero and Firefox remain not integrated |
I suggested if we can have a general solution for any inter-app communication rather than a specific one for web browsers: #1191 (comment). I haven't thought about the case of LibreOffice; that's good to know. Do they have restrictions (for example, the size of data that can be exchanged) like web extensions? Edit: To clarify, that’s for a long term solution, that’s unrelated to the current PR (which is a "quick" fix). |
This is a proposal for a new portal to enable the native messaging feature of sandboxed browser apps, which was originally discussed on the snapcraft forum.
Native messaging is a mechanism implemented in several major browsers (Chromium, Firefox, Brave, Edge, others?) that allows web extensions to communicate with a native application installed on the system.
This mechanism is used by different types of applications to provide better integration between the user’s computer and their browser / web services, for instance password management applications, searching and managing GNOME shell extensions, KDE Plasma integration, …
This currently doesn’t work in browsers (such as Firefox) packaged as flatpaks or snaps, because confinement prevents the browser from executing random executables on the user’s host (for obvious security reasons).
The native messaging host is described by a JSON metadata blob that looks something like:
In particular, you have:
name
that the web extension requests to talk topath
to the program that will be executedallowed_extensions
(for Firefox) orallowed_origins
(for Chrome) that the server is willing to talk toThe proposal is to expose a new
org.freedesktop.portal.NativeMessaging
interface, with aStart(…)
and aKill(…)
method (names up for debate):When called, the service would look for a matching JSON metadata file and verify that it allows communication with the named extension. If so, it spawns an instance of the app and returns stdin and stdout file descriptors that are pipes to the equivalent descriptors of the app. The
Kill(…)
method would let the browser terminate the app.This would prompt changes in browsers to use this new portal. Here in Firefox, and likely here in Chromium.
The text was updated successfully, but these errors were encountered: