Allowing xdg-open to open files


#1

At the moment snapd allows applications to call xdg-open to open http and https links, but could it be extended to open files as well?

For example:

A desktop snap allows the user to download a file, let’s say it’s a LibreOffice .ods file. This file gets placed in the user’s Downloads directory, and the snap offers the user the ability to open that file by clicking on it from it’s UI.

Opening that file wouldn’t work because it’s not an http[s] link.

I can see that this opens a potentially large hole, so perhaps a special interface is the right approach?


#2

I think xdg-desktop-portal might help here. That should include file open, iirc. @jamesh can you please confirm? Hopefully portals will at least handle the case of opening files using
g_app_info_launch_default_for_uri.


#3

The two things are orthogonal. We do want portals to work, but we also want good old xdg-open to work.

I suggest we start with something equivalent to what we did with xdg-settings: accept the snap request and ask the user to confirm the intention.

We can eventually remember decisions like this so we don’t bother the user repeatedly, but we need to be careful about it. Opening different files comes with different security implications.


#4

I agree with @niemeyer. We don’t, for example, want the snap to use xdg-open and have userd blindly call the handler without (at least some initial) feedback from the user since the snap might try to exploit bugs or features in the handler to escape confinement, and the user needs to express the intent for the snap to use the handler. We’ll want to be very careful with the handling of the filename to not introduce shell metacharacter escapes as well.


#5

Hey, we had some discussion in the channel, one thing that IMHO should be allowed (and @jdstrand was kinda agreeing from a security point of view) was to use the (trusted) filemanager as if it’s the browser, then leaving to the user the choice weather to open or not a file.

My idea was to apply this to just file:// where the pointed path is a directory, as it does firefox when you ask to open the container folder or Telegram too.

However, I think we could just expand this role by using the org.freedesktop.FileManager1 interface to all the files.

So basically when a file:///any/path/to/file.ext is sent to xdg-open we can just call the Filemanager’s ShowFolders method: if the pointed file is a folder, it will be just opened for browsing. If it’s a regular file, the containing folder will be opened and the file only selected. So, the snap itself won’t have any power to launch anything else.

The only thing that will happen is a dbus call, that might eventually open the filemanager implementing that interface (say nautilus).

So something like for a dir:

gdbus call --session --dest org.freedesktop.FileManager1 \
           --object-path /org/freedesktop/FileManager1 \
           --method org.freedesktop.FileManager1.ShowFolders \
                   "[\"file://$(xdg-user-dir PICTURES)\"]" ""

And this how it works for a file:

gdbus call --session --dest org.freedesktop.FileManager1 \
           --object-path /org/freedesktop/FileManager1 \
           --method org.freedesktop.FileManager1.ShowFolders \
                   '["file:///var/lib/snapd/state.json"]' ""

And this will work without portals, even for apps that won’t use it.


Call for testing: Telegram Desktop
#6

Popping a file manager with a file selected, without any context, and in which just pressing enter will run arbitrary and potentially dangerous actions, feels undesirable.

The idea presented above still sounds better: we would pop an actual dialog telling the user what’s going on, and also which specific snap is trying to do it, and let the user choose.


#7

Well true, but that’s the same in any web browser too, it’s that in that case there’s another confinement level, though. So while I agree that for files this might be still a bit more dangerous, what about enabling this for directories at least?


#8

I don’t get the analogy with web browsers. Can you expand a bit?


#9

Even a malicious snap could point to a phishing (say) site, and that is of course allowed as it’s not our role to educate users in controlling their actions.
At the same time, I wouldn’t consider allowing an user to open a file-browser to access to some content (which he should explicitly open) a security issue per se.


#10

The difference with a browser is that browsers are coded for phishing. The url is prominently displayed, there are noisy certificate checks and some browsers even have lists of phishing/otherwise bad sites. As a result, the snapd team decided that opening http/https URLs was ok.

With your idea, we now need to decide if the file manager is sufficient to convey enough information to the user to make an informed choice. It is easy for a malicious snap to point the file browser at a directory under its control with attack code that otherwise looks like the user’s home directory and/or files, and then trick the user into launching that code, which is now run outside of confinement. I would argue that users are trained to look at browser URLs and warnings more than file manager directories (which has no warnings) since people have been talking about phishing for years, where phishing via the file manager with snaps is new.


#11

FYI, future versions should allow the core snap’s xdg-open to open local files:


The changes have been merged to the 2.31 maintenance branch, so should be available soon.

The /usr/bin/xdg-open in the core snap will now accept local file paths, including relative paths. It then calls the new io.snapcraft.Launcher.OpenFile D-Bus method, passing a file descriptor to prove that the confined application has access to the file. Outside the sandbox, snap userd will show a graphical permission prompt and then launch the file using the real xdg-open.

This feature also supports opening directories, causing them to be opened in the file manager.


#12

Will this work for any kind of files? Like jpeg’s pdf’s etc? Do I need some special interface for this or will it “just start working” ?


#13

This works, it’s a significant UX improvement, thanks!

However if the handler picked by xdg-open to open the file is itself a confined snap, it will fail to open it because it can’t access it. A typical example would be downloading a .doc file with the chromium snap, and having the libreoffice snap installed as the default handler for this type of files (can be achieved by installing the libreoffice snap and removing the deb):

Allow snap "chromium" to open file "/home/osomon/snap/chromium/266/Downloads/sample.doc"?

clicking “Yes” results in a libreoffice error dialog:

Access to /home/osomon/snap/chromium/266/Downloads/sample.doc denied.