flatpak / flatpak

Linux application sandboxing and distribution framework
https://flatpak.org
GNU Lesser General Public License v2.1
4.25k stars 406 forks source link

Invoking Flatpak applications like they’re in $PATH #994

Closed fbruetting closed 6 years ago

fbruetting commented 7 years ago

Hey guys, can Flatpak applications be made invokable by just typing their names into the CLI? So for example when have just the flatpaked version of Gedit installed, I’d like to execute it by gedit.

Don’t know how to handle multiple installations… but this at least would improve handling of single installations.

TingPing commented 7 years ago

If you use BASH: alias gedit="flatpak run org.gnome.gedit"

fbruetting commented 7 years ago

Yeah, an automatic manner would be great. ;) But thanks!

TingPing commented 7 years ago

It can't do gedit for obvious security reasons and org.gnome.gedit is barely more useful of an alias.

fbruetting commented 7 years ago

I wanted to ask if Flatpak applications in general could provide such an option.

TingPing commented 7 years ago

If the application isn't strongly sandboxed it could write to ~/.local/bin but again this is just a security concern, you can't safely add random executables to PATH.

fbruetting commented 7 years ago

Ok thanks, wasn’t that obvious to me.

smcv commented 7 years ago

you can't safely add random executables to PATH

wasn’t that obvious to me

For clarity, here is the attack that this prevents:

You are probably about to say "but why could com.example.ShoppingList create pass and not just shopping-list?" - but from Flatpak's point of view, there is no reason why shopping-list is any more closely associated with that app than pass is. If you're about to suggest a name-based heuristic, imagine that instead of installing com.example.ShoppingList I installed org.example.Driving.Theory.Test.Practice.Guaranteed.Pass, cunningly named by the attacker to defeat the heuristic...

fbruetting commented 7 years ago

Thanks for your extensive elaboration, but after installing taskwarrior out of the distro repositories, this is invoked by task. So it seems to me, that this attack is still applicable for those applications…?

ramcq commented 7 years ago

My idea for this was that apps would use an export folder which wasn't put on the PATH, such as commands or something similar. Flatpak or another helper binary would be integrated by the distro or user in the shell config to:

ramcq commented 7 years ago

Oh yeah, this commands folder obviously doesn't need to contain the commands, just their names, so it could be any format. Maybe even a X-Flatpak-Command field in .desktop files?

fbruetting commented 7 years ago

Or to restrict applications to just provide executables with their package name.

I think that examples like smcv’s concatenated names should not be able to be that easy in gnome-software (at a time when this is considered standard), because there the displayed package name would just be the last component – and when a user does this by CLI, he/she may should have the knowledge to avoid this.

smcv commented 7 years ago

So it seems to me, that this attack is still applicable for [RPM] applications…?

Apps installed from RPMs are totally trusted. They can execute arbitrary code as root in scriptlets.

smcv commented 7 years ago

I think that examples like smcv’s concatenated names should not be able to be that easy in gnome-software (at a time when this is considered standard), because there the displayed package name would just be the last component

It isn't, though. org.example.Driving.Theory.Test.Practice.Guaranteed.Pass would appear as "Driving Test Practice" or something. The displayed name has no guarantee of resembling the machine-readable name at all: org.gnome.Nautilus is "Files" and org.gnome.Evince is "Document Viewer".

cgwalters commented 7 years ago

Apps installed from RPMs are totally trusted. They can execute arbitrary code as root in scriptlets.

@smcv Totally true, but just as an aside you might find this interesting: https://github.com/projectatomic/rpm-ostree/pull/888

chikamichi commented 6 years ago

See #1188 and related commit.

TingPing commented 6 years ago

This can probably be closed since you can add ~/.local/share/flatpak/exports/bin and /var/lib/flatpak/exports/bin to PATH and it provides simple wrapper scripts.

The names are still app-ids but as mentioned that is ideal to avoid overriding system tools.

nedrichards commented 6 years ago

Agree. Further tasks such as improving exports of autocomplete etc. can be separate issues.

xeruf commented 5 years ago

But snapcraft is able to drectly integrate applications into the path as well. Why can it do that and flatpak can't? Calling "org.gnome.gitg" whenever I simply want to access gitg is super annoying, and I'd like to not have to manually set an alias...

DomingoMontoya commented 5 years ago

Worried a flatpak could be run, instead of the intended system installed program?

Simple - put flatpack install folder last in $PATH.

refi64 commented 5 years ago

This hasn't been done to avoid Flatpaks conflicted with each other, not necessarily just with the system.

DomingoMontoya commented 5 years ago

I have to say that I do prefer having the option that snaps have to use the --classic flag to allow it. It's also nice that the --classic snaps allow my installed snaps to use the configs in my $HOME dir, which also has the added benefit of all my personal data being in one folder during backup/restore.

smcv commented 5 years ago

Worried a flatpak could be run, instead of the intended system installed program?

Simple - put flatpack install folder last in $PATH.

This would prevent a flatpak app from overriding a system executable like pass(1) when typed correctly, but wouldn't prevent it from performing a "typosquatting" attack by installing an executable named pas or pss or similar and waiting for the user to mistype the system executable's name.

DomingoMontoya commented 5 years ago

I can see why it's not a preferable default, but an option to override for certain paks at install time would put that responsibility on the user.

fbruetting commented 5 years ago

What about a Flatpak starter program? So like fp nautilus for starting flatpaked Nautilus? As soon as there are conflicts, it can ask which one to start, just like flatpak asks when there are multiple installation options.

DomingoMontoya commented 5 years ago

That would be an improvement. My issue was with running a helper program that came in the package. I installed Atom text editor, but running apm [atom package manager] meant I had to go several layers deep into the flatpak dir to do so.

fbruetting commented 5 years ago

That’s a different thing. Here you should use the flatpak enter … command to go into the sandbox and invoke that program from inside.

Zzombiee2361 commented 3 years ago

Sorry for reviving this long closed issue, but I'd really like the devs to reconsider this. I have commented this on #4109, but to quote:

It's a shame that #1188 got locked when @refi64 made a great proposal on how this could work securely and with minimal problem.

One thing I would add is instead of aliasing a whole application, the app could list which executable to export. This would facilitate application that has multiple commands or extra tools (e.g. Android Studio).

$ flatpak bin-export com.google.AndroidStudio

The application com.google.AndroidStudio would like to export these binaries:

  [ ] Select All
  [ ] adb (Binary already exists in PATH!)
  [x] android-studio
  [ ] dmtracedump
  [x] fastboot

Please choose which to export. Press space to select and enter to confirm.

The conflicting binary could be highlighted in red, but could be selected to override the one in PATH if the user really want it. Unfortunately I don't quite know how to handle when the binary name changes during update. Probably some people with knowledge could improve on this proposal.

ghost commented 3 years ago

i3wm does not see programs installed via flatpack. How can this be changed as an example installed telegram-desktop or viber

bast1aan commented 3 years ago

FWWI, I am using this simple script as a workaround to be able to run Flatpak applications from CLI (or my ALT+F2 runner) with their original binary names.

#!/bin/bash

# Put file in /usr/local/libexec/flatpak-runner and then
# symlink for instance /usr/local/bin/spotify to ../libexec/flatpak-runner

declare -A pkgs
pkgs=(
 [spotify]=com.spotify.Client
)

cmd=`basename $0`
args=$@

flatpak run --command="$cmd" ${pkgs[$cmd]} $args
matkoniecz commented 2 years ago

If you use BASH: alias gedit="flatpak run org.gnome.gedit"

Has anyone got an idea how to add it automatically when program are installed with an Ansible?

For reference: doing https://github.com/matkoniecz/recovery-with-ansible/commit/e0eb03cd903508afb46de8a64f69c8c06506be76 needed also https://github.com/matkoniecz/dotfiles_public/commit/b40a2b2e96ec596f6397045493dd1aa715d28d5e

wpietri commented 2 years ago

I don't have a strong opinion on the right solution, but let me write up the user problem I have here.

I'm using PopOS, which defaults to installing some things via Flatpak. I installed Flameshot to take screenshots. That works fine if I launch the app and invoke it through the icon in the top bar. But if you want to take a screenshot of, say, an on-hover panel, you need to trigger it via keystroke. How to set that up? The recommended option is to use Settings to create a keyboard shortcut that calls /usr/bin/flameshot gui. That just silently fails, because there is no Flameshot binary in that spot. Or anywhere in the path.

Through a bunch of detective work, I eventually figured out what the problem was. But the easy user solution here is just "uninstall the flatpak and install the regular OS package". If that's the solution Flatpak's maintainers want people to pick, the current behavior is fine. If not, I think there needs to be a better story about compatibility with standard CLI usages.

sztomi commented 2 years ago

The official tutorial for creating a flatpak recommends installing flatpak-builder via

flatpak install flathub org.flatpak.Builder

And then uses the command as flatpak-builder but that's impossible, it has to be ran as flatpak run org.flatpak.Builder. I thought that something was wrong with my system, and that's how I found this issue. This is really confusing and user-hostile behavior. All the justification about clashing commands is not really a strong argument in my opinion. Yes, it's annoying when that happens, but it happens rarely and easily fixable. Burdening the default case with this obscure behavior is a bad choice.

matkoniecz commented 2 years ago

And then uses the command as flatpak-builder but that's impossible

I guess that it should be reported as bug if not done already

sztomi commented 2 years ago

I agree, but that's not really my point. Even the official documentation get this wrong because the obvious way is different from how it's done currently.

markfaine commented 2 years ago

I'm hoping that this was all a waste of time and there is already a way to do this by now and I just missed it in the docs and google searches but if not this was my clumsy attempt at fixing it for now.

https://gist.github.com/markfaine/ce346b83303fe75444374001517a73a7

rijnhard commented 1 year ago

https://github.com/flatpak/flatpak/issues/994#issuecomment-1007917011

Seriously can we bring this back to the table, from a user perspective it's such a good proposal.

e.g fwupd with prospective DE integration, allowing it to be installed with flatpak and used globally is such a benefit, and of course this is something I would want to only allow in certain cases when I trust the app.

markfaine commented 1 year ago

#994 (comment)

Seriously can we bring this back to the table, from a user perspective it's such a good proposal.

e.g fwupd with prospective DE integration, allowing it to be installed with flatpak and used globally is such a benefit, and of course this is something I would want to only allow in certain cases when I trust the app.

I went back to snap on Ubuntu. If you can't run it from the command line the same way you would if it were installed using an ordinary package manager then, in my opinion, it's not quite ready for prime time. I will continue using snap for now, but long-term I'm probably looking at nix. Having said that, I still agree and would like to see this issue brought back up.

badbabykosh commented 1 year ago

This is breaking everything in the software ecosystem that needs to call Chrome from the command line. I've just spent hours surfing for a solution to my specific problem (indium not finding "chrome" in PATH since it is flatpak now) and finding a number of others with same issue (i.e. Sellinium, cypress.io, etc )....just thought I'd mention this.

sztomi commented 1 year ago

A little aside, I attempted to use the vscode flatpak with an alias. But contrary to how other vscode installations work, the flatpak run command (aliased to code) will direct stdout to the current terminal, so launching vscode from the current directory via code . will fill it up with various warnings and errors.

rijnhard commented 1 year ago

I'm wondering if this is actually being seen by the flatpak maintainers, since its closed.... Dont want to create a new issue for this if that is the case, but if they arent seeing it then I do think its valuable for a lot of people to create another issue and link this.

ramcq commented 1 year ago

This is breaking everything in the software ecosystem that needs to call Chrome from the command line. I've just spent hours surfing for a solution to my specific problem (indium not finding "chrome" in PATH since it is flatpak now) and finding a number of others with same issue (i.e. Sellinium, cypress.io, etc )....just thought I'd mention this.

I don't quite understand this; I have all of the browsers on my system installed as Flatpaks and everything works fine. Flatpak populates wrapper scripts in /var/lib/flatpak/exports/bin for each Flatpak, which you can add to your PATH, so you can successfully launch the browser via a) XDG defaults, b) the desktop file, c) the wrapper script:

ramcq@xi:~$ xdg-settings get default-web-browser
org.mozilla.firefox.desktop
ramcq@xi:~$ echo $PATH
/sysroot/home/ramcq/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/sysroot/home/ramcq/.local/share/flatpak/exports/bin:/var/lib/flatpak/exports/bin
ramcq@xi:~$ which org.mozilla.firefox 
/var/lib/flatpak/exports/bin/org.mozilla.firefox

If you have something that hardcodes/presumes the browser is called chrome in your $PATH, and doesn't respect the XDG browser settings, then tbh it's broken, but you could work around by adding a symlink (ln -sf /var/lib/flatpak/exports/bin/org.chromium.Chromium ~/.local/bin/chrome or whatever).

ramcq commented 1 year ago

I'm wondering if this is actually being seen by the flatpak maintainers, since its closed.... Dont want to create a new issue for this if that is the case, but if they arent seeing it then I do think its valuable for a lot of people to create another issue and link this.

I don't think it will make much difference, Flatpak is a little under-maintained right now - the folks involved with Flatpak maintenance are mostly looking at sandboxing and security issues, rather than "CLI UI".

But that said, I think if someone sufficiently motivated showed up with a mechanism for a Flapak to export >1 command (eg adding a "commands" to the JSON with a list of binaries in /app/bin which could be exported) it could be argued for pretty easily. Then you could have more of those wrapper scripts, app.id-foo and alias/link/etc them as you wished.

rusty-snake commented 1 year ago

I think if someone sufficiently motivated showed up with a mechanism for a Flapak to export >1 command (eg adding a "commands" to the JSON with a list of binaries in /app/bin which could be exported) it could be argued for pretty easily. Then you could have more of those wrapper scripts, app.id-foo and alias/link/etc them as you wished.

If I understand you correct, the maintains already said NO to this, in this issues: https://github.com/flatpak/flatpak/issues/994#issuecomment-328154457

rijnhard commented 1 year ago

I think if someone sufficiently motivated showed up with a mechanism for a Flapak to export >1 command (eg adding a "commands" to the JSON with a list of binaries in /app/bin which could be exported) it could be argued for pretty easily. Then you could have more of those wrapper scripts, app.id-foo and alias/link/etc them as you wished.

If I understand you correct, the maintains already said NO to this, in this issues: #994 (comment)

Well, to be specific they said no to a blanket approach. That doesn't mean that there can't be a UI component & an associated spec that allows this.

e.g. something in the spec that specifies:

then provide an additional CLI flag

--export-command=[primary(default)|all|<specific>=<override>]
# it should fail if a command already exists in path that matches that command name

This then doesn't become a security risk unless you are an idiot and install an untrusted flatpak using --export-command=all, but I haven't seen much about where the flatpak methodology is preventative in this way unlike snaps.

@smcv would this not still meet your criteria for preventing the type of attack you mentioned, noting that the all option is obviously the risky one.

Final edit: I also would keep this either as an explicit flag or even a separate subcommand, and would definitely not provide an option to globally set this behaviour by default.

sztomi commented 1 year ago

This is a closed issue so I'm not sure the discussion here matters at all, but I'd like to point out that the whole security risk is quite misplaced in my opinion. The decision of flatpaks to be decentralized gives freedom but also responsibility to users. There is nothing stopping a malicious actor from packaging a foo.bar.TrusworthySoftware.WellKnownCompany and publishing it in their own (or a not vetted third-party) repo. Users need to be careful about selecting the sources they install from and this is their responsibility, exporting commands or not. Hijacking a flatpak ID is not much different from hijacking a given CLI command. If flatpaks were to export commands (which is the user expectation) Flathub could (and should) vet packages for CLI command hijacking.

rexackermann commented 1 year ago

I was thinking to use this:

f() { flatpak list | grep $1 | awk '{ print $2 }' | xargs flatpak run } in my .zshrc.

to open any app f \<app-name>

DLopezJr commented 1 year ago

@fbruetting

What about a Flatpak starter program? So like fp nautilus for starting flatpaked Nautilus? As soon as there are conflicts, it can ask which one to start, just like flatpak asks when there are multiple installation options.

In progress.

@RexAckermann You inspired me to extend on your idea. I'm very happy with the prototype I have up here: https://github.com/dlopezJr/fp/

Template

$ fp <package_name> <$2>

Example

$ fp vlc --help

I will work on getting this to be very resilient so that upstream can take it or it can be packaged and distributed by distributions.

ikluft commented 1 year ago

I wish I had seen this discussion years ago. I have a script that I call from my .bashrc which makes shell aliases for the basename of each Flatpak. I posted it at https://github.com/ikluft/ikluft-tools/blob/master/scripts/flatpak-aliases.pl .

An option could be for distro Flatpak installations to include a script to do this from /etc/profile.d .

ChristianSilvermoon commented 1 year ago

I know this was closed way earlier, but to inject my two cents

I've had basically this as part of my .bashrc for a long time now and it more or less solves this issue from a shell.

I also have the export directories in my $PATH

# Alias all flatpaks to their logical command names, but only if they're not already commands.
# tld.domain.AppName becomes the alias "appname"
# if "appname" is already used by another command then "tld.domain.AppName" is used instead.
# If both are used, nothing is aliased.

alias_flatpak_exports() {
    local item
    for item in {${XDG_DATA_HOME:-$HOME/.local/share},/var/lib}/flatpak/exports/bin/*; do
        [ -x "$item" ] || continue

        local flatpak_short_alias="${item//*.}"
        local flatpak_long_alias="${item//*\/}"

        if [ ! "$(command -v "$flatpak_short_alias")" ]; then
            alias "${flatpak_short_alias,,}"="$item"
        elif [ ! "$(command -v "$flatpak_long_alias")" ]; then
            alias "$flatpak_long_alias"="$item"
        fi
    done
}
magical-heyrovsky commented 1 year ago

@DLopezJr

Inspired by your solution but with

.zshrc:

# fp auto-completion
() {
  # A list of each flatpak app name in lowercase.
  # (First word of the name to be exact, so "Brave Browser" will be "brave").
  local FLATPAK_APPS=$(flatpak list --app | cut -f1 | awk '{print tolower($1)}')
  complete -W $FLATPAK_APPS fp
}

# Run Flatpak apps from CLI, e.g.: "fp okular"
function fp() {
  app=$(flatpak list --app | cut -f2 | awk -v app="$1" '(tolower($NF) ~ tolower(app))')

  # Abort if the app name was not entered
  test -z $1 && printf "Enter an app to fp.\n\$ fp <app>\n\nINSTALLED APPS\n$app\n" && return;

  # Remove app name from "$@" array
  shift 1;

  # Run the flatpak app asynchronous and don't show any stdout and stderr
  ( flatpak run "$app" "$@" &> /dev/null & )
}

So far no problems :)