Open hadess opened 4 years ago
From https://github.com/flathub/flathub/pull/1415, sqlite would like to be able to write the main db, as well as some files in the same directory such as its journal.
I wonder if its valuable to limit it to just specific files matching a pattern rather than all of a directory.
I wonder if its valuable to limit it to just specific files matching a pattern rather than all of a directory.
Maybe, for something like video players wanting to access subtitles, but that might be complicated for all other types of projects, where the name/extensions of assets wouldn't be known until the main file was parsed.
Yeah media players is what I was thinking of, using a pattern could improve the UX, it could know no other files match and just behave as normal without constant double prompts.
Am I wrong to expect this to be just an option in the OpenFile method of the file chooser ?
Am I wrong to expect this to be just an option in the OpenFile method of the file chooser ?
The priority would be to discuss the UI and the use cases for now, not the implementation. This will tell us whether we want an option for the OpenFile method, or something else. For the media players use case discussed above an option won't be enough, as we need to return multiple files.
I feel this is going to get very complicated. At some point you just have to concede and accept a gaping hole in the sandbox for certain kinds of applications. Music and video apps that need access to companion .cue or .srt files will just need access to the same folder (and subdirs) so they can load those files. Otherwise you need various mechanisms of increasing complexity to allow the portals to figure out which files to give access to.
For fun I could think of using javascript programs that is submitted by the app via the portal API and which will parse the selected file in the file chooser and spit out a list of associated filenames. But for very complex file formats this could be a daunting task. For things like .srt and .cue it should be fairly trivial to write some javascript for that purpose. With very limited API surface in the jvm this could be made perfectly safe and it would only understand a list of filenames coming from the script and it would have to be limited to the folders that the flatpak app currently has permissions to access. Or if not javascript maybe even some DSL that is designed with functions to open, read, seek and do data conversions. Or even BPF.
My skin in the game here is that I currently maintain a flatpak manifest for DeaDBeeF music player. So mp3/cue is something I would like support for opening.
In case more use cases are wanted: the Inform compiler takes as input a project folder "Foo.inform" (which the user can select with a file chooser in the UI) and expects to be able to create an assets folder "Foo.materials" as a sibling of "Foo.inform".
I think this would be able to be handled by a new option for the OpenFile method.
And more use cases: currently I have to disable the sandbox in Apostrophe because otherwise I can't render a markdown document with images (which are not embedded due to the plaintext nature of markdown)
I can see the same happening for IDEs, which need access to a whole folder, or any kind of editor where data is linked instead of bundled
Another media player use case in https://github.com/flathub/io.github.celluloid_player.Celluloid/issues/28
Hello ! It is also needed for playing external audio files (and maybe video files) linked to PDFs (software use here: GNOME Document Viewer [Evince]) in full sandboxing.
Apps that run win32 binaries via Wine, e.g. Bottles and protontricks, could benefit from this as well. An .exe
can be opened via portal, but if it's not self-contained and require some .dll
s in the same directory, it won't work.
For image viewers like EOG, we want to be able to browse images adjacent to the one the user opens.
Aside from GTK applications that haven't yet migrated to GtkFileChooserNative
yet, this is probably the number-one reason I have huge exceptions in my sandboxing:
file://
URLs and need to write _files
directories when Ctrl+S-ing..edl
files I generate to skip ads, sponsor notices, and the odd skit that goes on too long in old Spoony videos. (Currently, I've used overrides to disable MPV's network access and grant host:ro
.).bin
files when they open .cue
filesThere's an adjacent issue - when passing a URI (for opening via the file manager or app chooser portal) apps also need a way to handle that. A solution for GtkFileChooser doesn't work for every case.
Regarding the UX aspect of this: a clear and non-confusing API for this, is to:
Some things I kept in mind:
When starting applications that take a file as an argument (e.g.: an image viewer when double clicking on a file in a file manager), it would also be handy to sometimes have access to the directory containing the file.
For example, if I double click on an image, I want an image viewer to render it. But I also want to easily navigate back and forth across sibling images. Having to grant the flatpak access to that whole directory ahead of time is very inconvenient.
The same applies to double clicking on videos which have separate subtitles. This scenario doesn't go via a FileChooser portal, so might be trickier.
There's an adjacent issue - when passing a URI (for opening via the file manager or app chooser portal) apps also need a way to handle that. A solution for GtkFileChooser doesn't work for every case.
Another case where I ran into this: LibreOffice has a Help extension, and tries to open it in the system browser. The browser, if it is also sandboxed, gets access to index.html
but not the neighbouring files. #555
@hadess: Assuming the goal is to at least always read files, isn't it safe to automatically allow apps to only read files? Isn't the problem in writing files?
@Mikenux I assume it'd reduce the threat potential... though there would still need to be some way to allow write access for things like opening a project in an IDE (open the project definition in the root of the project and get access to the rest of the source files) or using "Web Page, Complete" when hitting Ctrl+S in a browser.
isn't it safe to automatically allow apps to only read files?
Is your proposal that the ordinary File -> Open
file-chooser should always give read access to the entire directory containing the selected file?
The problem is that we can't guess what the user wants, so a UI for doing this sort of thing would need to be really clear about what is going to happen, to set up the right expectations. Otherwise, anyone whose expectations don't match the reality will be justifiably upset.
If you browse to ~/Pictures/2022/landscapes
and open one photo, you might reasonably expect that an image viewer will be able to see other photos in the same directory. But, if you browse to ~/Documents
and open ~/Documents/funny picture of a cat.jpg
, you might be extremely upset to find that the same application (perhaps a chat app) can now read ~/Documents/banking details.pdf
. The portal cannot programmatically tell the difference between your expectations in those two cases.
@ssokolow : Of course, there's the case for write access, but if it's possible to not ask the user to read files, that's better. I mean regular users expect to have a dialog asking them to write a file (save) more than a dialog asking them to read a file or directory (open/list).
@smcv: As I just told ssokolow, the goal is to not even prompt the user in case of "read". Regarding your example, are you talking about automatically reading files and the application sending them over the network? If so, if the chat app automatically read bank details.pdf
, I wouldn't be "extremely upset" because I wouldn't notice it doing so. If I open this same file with a PDF reader, I don't know what the PDF reader can do with the file. The same goes for pictures that I don't want to "share" without consent. Also, even if you grant access through a dialog box, you are sure that the app wants to read files, but you don't know what the app will do with the files. The only advantage is like in your example: countering possibly malicious readings. So if it is the app reading user files and then sending the retrieved information to the internet, maybe in this case the apps without network permission can get the read access without consent. I'm clearly not an expert, I just think the direction to take is to know the cases better to disturb the user less with dialog boxes...
Implementing this functionality in a way where the user doesn't realise they're sharing more than the file they thought they selected is a non-starter.
@Mikenux You're right that asking less questions is good, but not asking questions at all, or asking questions that aren't understood is clearly worse.
I don't think there's any point discussing this functionality until we know how the UI should be designed. Prior art from other OSes and applications would be useful.
So if it is the app reading user files and then sending the retrieved information to the internet, maybe in this case the apps without network permission can get the read access without consent.
@Mikenux The application without network access might have D-Bus access to something that does have network access and can be used to perform an HTTP request for them. It's known as the confused deputy problem and it's one of the reasons defence in depth like this is necessary.
isn't it safe to automatically allow apps to only read files?
No, other files may contain sensitive or confidential information, access should never be granted automatically.
I don't think there's any point discussing this functionality until we know how the UI should be designed.
I think it's good to continue enumerating distinct use cases so we can make sure we design in a way that catches all corner cases.
Prior art from other OSes and applications would be useful.
I don't think there is much, but IIRC, on macOS applications can prompt for permissions to access an entire directory, but only for well-known ones. There's also no granularity.
I think a good approach UX wise is to use the regular filechooser, and then show a small followup dialog asking for permission to read neighbouring files. This keeps complexity (UX wise) to a minimum, but also makes the extra access request explicit. Being a separate yes/no dialog prevents accidental confusion.
I don't think it can be less than two click when you're asking for two distinct permissions, and granting access must always be explicit (eg: a small checkbox at the bottom of a file chooser is easy to miss).
I think a good approach UX wise is to use the regular filechooser, and then show a small followup dialog asking for permission to read neighbouring files. This keeps complexity (UX wise) to a minimum, but also makes the extra access request explicit. Being a separate yes/no dialog prevents accidental confusion.
I don't think it can be less than two click when you're asking for two distinct permissions, and granting access must always be explicit (eg: a small checkbox at the bottom of a file chooser is easy to miss).
That'd be a distinct annoyance and incentive to continue packaging with looser manifest permissions for anything like an IDE where the typical case is going to be granting the entire folder.
I think it's important to keep brainstorming.
(Bear in mind that, from what I remember, the big hold-up for getting things like GIMP and Inkscape onto GtkFileChooserNative
is whether they're willing to risk regressing the in-chooser preview pane. Maintainers can be picky about these things.)
I think a good approach UX wise is to use the regular filechooser, and then show a small followup dialog asking for permission to read neighbouring files. This keeps complexity (UX wise) to a minimum, but also makes the extra access request explicit. Being a separate yes/no dialog prevents accidental confusion.
I don't think it can be less than two click when you're asking for two distinct permissions, and granting access must always be explicit (eg: a small checkbox at the bottom of a file chooser is easy to miss).
If either having 2 dialogues, or a checkbox in a dialogue were good enough, then it would already be implemented. It isn't...
That'd be a distinct annoyance and incentive to continue packaging with looser manifest permissions for anything like an IDE where the typical case is going to be granting the entire folder.
IDEs can already use the OpenFolder portal.
IDEs can already use the OpenFolder portal.
We could have a new permission for Flatpaks that elevantes all "open file" calls to "open file and neighbouring files".
So something like an IDE can [at install time] request this permission, and then any time a file is opened, so it the directory.
This gives really good usability for this kind is scenario, but makes it impossible to open a file without sharing the entire directory.
I do believe there are scenarios where this approach is the one that makes sense the most, but for other type of applications, the second pop up is still best. In reality, the new permission would skip the dialog on the second call and always grant the followup request.
Not all IDEs and IDE-like things use "Folder containing a Well Known filename" as their structure. Some have a project file with an arbitrary name such that you could have multiple projects sharing a single folder.
You have to explain why the OpenFile
with the directory
option doesn't work in that case because I don't get it.
There seems to be three relatively unrelated use cases
The first one is for example IDEs, video editors, etc. They can use the OpenFolder portal to add workspace directories.
The second one is really tricky. Maybe we could have some heuristics in the portal which checks the file type/mime type and filename to figure out if the whole folder might be required. In that case the user can be told that the entire directory might be required and let the user pick between "entire directory" or "only this file" with default to "entire directory".
The third one might actually be a good candidate for a static permission listing the mime types of objects it wants to be able to browse. Not sure about it at all though.
You have to explain why the
OpenFile
with thedirectory
option doesn't work in that case because I don't get it.
Because the application wants you to select some form of ArbitraryName.project
file, rather than the folder it resides within, but then needs to access its siblings within the folder. (Similar to Foo.html
and Foo_files
with saved web pages.)
Because the application wants you to select some form of ArbitraryName.project file, rather than the folder it resides within, but then needs to access its siblings within the folder. (Similar to Foo.html and Foo_files with saved web pages.)
That's just a broken app then which doesn't use the directory
option when it should?
e: if the app really only wants to open folder with the filename "ArbitraryName.project" in it maybe we can add an directory_requires_filename
option to the OpenFile portal.
That's just a broken app then which doesn't use the directory option when it should?
No, it's an app that wants a file, which depends on other files. Would you say a web browser is a "broken app" for not using a directory picker and then implementing its own file picker to choose between the HTML files within the picked directory?
e: if the app really only wants to open folder with the filename "ArbitraryName.project" in it maybe we can add an
directory_requires_filename
option to the OpenFile portal.
If, by that, you mean that it displays a file picker, mounts the containing folder into the documents portal as if it were selected in a directory picker, and then returns the document portal path to the picked file, that would certainly work.
The part that complicates things is that whole "Application needs access to the folder, but can't derive the file's name from it because there may be more than one".
@ssokolow :
@Mikenux The application without network access might have D-Bus access to something that does have network access and can be used to perform an HTTP request for them. It's known as the confused deputy problem and it's one of the reasons defence in depth like this is necessary.
If an application has access to something that has network access, I believe the application is not fully sandboxed. If an application has this type of permission, even if you ask the user to read a file/directory (so several files), it does not prevent this application from sending these files afterwards. The only protection is possibly when the application wants to read a file while the user is not aware of it (in the case where the application can only read one file at a time). Am I right?
There are requests for prior art but there is none. Other platforms just request blanket permission for single applications to your documents, pictures, downloads.
Flatpak has for reasons specifically opted to not go this route and instead let each app just specify sandbox exceptions in the metadata that the user needs to use third party software to control (FlatSeal). The only area where it seems to be some proper permission granting dialog boxes is for things like camera and screen sharing access.
Now work has completed on the feature that allows applications to resume camera and screen sharing sessions.
The design you go for will have consequences.
@ssokolow I misunderstood what you were saying and it indeed looks like it's a 4th use-case. The only way I see how this could be implemented is if the folder name is derivable from the filename, otherwise you just have to give up and open the containing folder.
@Mikenux Like most security situations, the confused deputy problem often comes up in situations where something isn't supposed to have access, but does by mistake.
That's why it's so important to have defense in depth... so if a flaw is found in the sandboxing for network access (eg. a detour through a D-Bus service that people writing the sandbox manifest didn't realize could be used to send network requests), the program still doesn't automatically have access to the potentially sensitive files.
(Look at how the log4j JNDI vulnerability happened, for example.)
@ssokolow : Yes. However, the ideal sanboxed application has access to nothing: no network access, no d-bus access to communicate with/to another application, no write access.
Regarding the portal, I mean that even if you ask users to grant access to files, users certainly do not know what the application will do with them. And as I said, users can use applications to open sensitive files (for example, the PDF viewer example I gave). So even if you have a portal between your files and an application (even to only open a single file, and especially a sensitive file), but that application has network access (via direct network access or a d-bus service) to do malicious things, it won't change anything. Continuing with the PDF viewer example, if the app is marked as insecure/potentially unsafe, but has functionality for sharing files over the internet, a user will definitely use it - and it is a malicious app. More than that, if this PDF viewer has the ability to open multiple files at once, the user will definitely grant it permission to do so. Finally, unless I'm completely wrong in this comment, you'll need more protection (more defense in depth) than just asking the user.
Could we keep the discussion on topic to use cases for this feature, ideas for UI design, and prior art? Debating the fundamental nature of sandboxing is interesting but makes it a bit difficult to follow for people like me who are trying to follow news of the feature :smile:
It seems that we have basically three scenarios:
I believe that (1) and (3) can be handled with an extra flatpak permission that needs to be granted. (2) and (4) are best addressed with the follow-up prompt.
Are (1) and (2) really different? The app probably can't tell ahead of time which sibling/child directories/files are needed. So shouldn't the user's choice be whether to allow access to the directory the file is contained in or not?
Seeing a prompt for (4) seems jarring. If a user opens a playlist file, they always want to allow access to the actual media files, no?
There is another issue to keep in mind. Are we allowing recursive file access? Some of those scenarios would require it (i.e, IDE folder structures usually work with subdirectories, resources for html/markdown files, etc). The obvious issue is that if recursive directory access is granted opening a file in HOME means having access to all files of the user. Maybe would be interesting to somewhere explicit what files are being accessed by the app, just as there are indicators for when the screencapture portal is being used, at least in GNOME
From: Teoh Han Hui @.> Sent: Saturday, February 26, 2022 3:20:45 PM To: flatpak/xdg-desktop-portal @.> Cc: somas95 @.>; Comment @.> Subject: Re: [flatpak/xdg-desktop-portal] Portal to open file and neighbouring files (#463)
Are (1) and (2) really different? The app probably can't tell ahead of time which sibling/child directories/files are needed. So shouldn't the user's choice be whether to allow access to the directory the file is contained in or not?
— Reply to this email directly, view it on GitHubhttps://github.com/flatpak/xdg-desktop-portal/issues/463#issuecomment-1052140319, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACEAIN7EROBYUIVBOPCVJXLU5DOT3ANCNFSM4LUL5H2Q. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you commented.Message ID: @.***>
Recursive access is so common that I actually had to think for a moment to come up with situations where you wouldn't need it. (With the browser-produced _files
sidecar folder probably being the most common example)
The situations I came up with which probably don't need it are:
.iso
. (Usually. the .cue
and .toc
files which are paired with .bin
files to define the disc layout support arbitrary relative paths as I remember, since they're essentially a specialized form of playlist file akin to a .pls
or .m3u
with the .bin
potentially just being the contents of a single data track. I don't know if CloneCD/CloneDVD pairs/triples can do that, nor for Alcohol 52%/120% pairs/triples, BlindRead/BlindWrite images, etc.).img
/.iso
as produced by normal dd
, paired with a .log
file that describes which segments failed to read, so the tool can be re-run to attempt to fill them in).par2
file is a bundle of ECC that sits alongside the files it protects and, for historical Usenet reasons, it might be split across multiple .par2
files.)...so, basically, formats that use a sidecar file to add metadata to something without altering its format, similar to Apple's AppleDouble format for storing resource forks and data forks side-by-side on non-HFS filesystems.
The more typical case is things such as any document format that links resources rather than embedding them, which has a 50/50 chance of keeping subresources in a sibling folder to organize them. (HTML, LyX documents and the LaTeX they render to, Inkscape SVG if you choose the Link radio button when importing an external image, etc.)
In fact, those could sort of be considered examples of "project workspaces which don't impose a specific Well Known Filename", since, from what I remember, LyX allows you to do things like having one .lyx
file per chapter with some subresources shared between multiple chapters, and a top-level .lyx
file which combines them into a single manuscript.
Are (1) and (2) really different? The app probably can't tell ahead of time which sibling/child directories/files are needed. So shouldn't the user's choice be whether to allow access to the directory the file is contained in or not?
The difference is whether the application sometimes requires extra access, or always.
An application that opens "project files" will always need access to sibling files, so it's reasonable to grant the extra permission once at installation time.
A browser opening an HTML file only sometimes needs extra access, so it's logical to only ask in those specific scenarios. Especially since opening ~/cat-meme.png
in Firefox shouldn't grant it access to my entire home right away.
Seeing a prompt for (4) seems jarring. If a user opens a playlist file, they always want to allow access to the actual media files, no?
I agree on the sentiment, but you can't know that the file is playlist before opening it. Not unless the portal itself is capable of recognising filetypes -- but that sounds like a pretty big rabbit hole.
@ssokolow thanks for additional good examples!
A browser opening an HTML file only sometimes needs extra access, so it's logical to only ask in those specific scenarios. Especially since opening
~/cat-meme.png
in Firefox shouldn't grant it access to my entire home right away.
Maybe files directly in the home directory should be special-cased, similar to how Flatpak blacklists various paths like /boot
, /root
, and /var
when you specify filesystem=host
.
Are (1) and (2) really different? The app probably can't tell ahead of time which sibling/child directories/files are needed.
I think that depends on the app? I think it'd be reasonable for, say, a media player to ask ahead of time for access to a sibling subtitle file with same name as the video file being opened, but with the extension replaced by .srt
, if such a file exists. Or in my use case, the Inform IDE, when the user opens Foo.inform
, to ask ahead of time for permission to access a sibling folder Foo Materials
and also permission to create it if it doesn't exist.
I think it'd be reasonable for, say, a media player to ask ahead of time for access to a sibling subtitle file with same name as the video file being opened, but with the extension replaced by
.srt
, if such a file exists.
Media players are an interesting case, because they straddle the line. Sometimes needing to access sibling files with predictable names (eg. subtitles) and sometimes needing paths that can only be derived after the file has been opened (eg. .pls
, .m3u
, XSPF, EDL, etc.).
Also, SubRip (.srt
) isn't the only subtitle format. for example, there's SubStation Alpha (.ssa
) and its advanced variant (.ass
) as well as the more interesting case of the subtitle files you'll get out of something like youtube-dl.
The Netherlands welcomes Trump in his own words-j-xxis7hDOE.mp4
The Netherlands welcomes Trump in his own words-j-xxis7hDOE.en.vtt
...and yes, MPV will automatically find the latter filename if given the former.
Another interesting case I can present, which I use a lot, is MPlayer/MPV Edit Decision Lists, which are basically playlist files that let to specify parts of files.
For example, I have a PySceneDetect-based script which wraps youtube-dl and produces EDLs, because The Young Turks is so bad about rapidly cutting into an irritating, carnival barker-esque "Wanna pay us to get even more content?" post-roll ad after each clip.
(Seriously. Sometimes, they cut so close that the last word in the actual content gets cut off.)
Activision-Blizzard Pushes COMICAL Anti-Union Propaganda [60QSENi88o0].mp4.mpv.edl
Activision-Blizzard Pushes COMICAL Anti-Union Propaganda [60QSENi88o0].mp4
Note that the file names are purely my own choice. The actual connection is made by the contents of the EDL file looking like this:
# mpv EDL v0
%74%Activision-Blizzard Pushes COMICAL Anti-Union Propaganda [60QSENi88o0].mp4,0,421.6212
We're missing a UI that would make it possible to opening a file, eg. a project file, and also give access to the rest of the files in that same directory. This is useful for:
UI-wise we could have:
New use cases, UI ideas, or prior art? Please list them below.