labwc and security #1002
Replies: 19 comments 34 replies
-
I think in terms of security the most important part is preventing some wayland / wlroots protocols to be used by clients:
If you want to see some of them in action you can try out https://github.com/Consolatis/wl_framework/blob/main/examples/wl_monitor.py There was also some work going on on the wayland-protocols side of things for sandboxing flatpaks: MR, Protocol (and wlroots MR). Even if that protocol is merged into wlroots it will take quite a while until labwc supports it because we are not currently tracking the wlroots dev branch. Another option could be to add a wayland proxy in between the actual compositor and the sandboxed clients, that one could then filter out some globals. |
Beta Was this translation helpful? Give feedback.
-
Thanks for that link, @Consolatis! I'll take a look.
Please do!
About flatpak: I don't use it. Many people consider it a sandbox, but it isn't a security sandbox. It has the rudiments of one, but it has conflicting purposes, and most likely the purpose of being convenient for a wide range of users will win out over being secure. Also, proper use of flatpak requires use of a non-sandboxed session dbus. BTW: Another aspect of labwc that helps with security is the ability to force server-side decorations, which I do using this in my rc.xml:
A client that uses only client-side decorations can position itself invisibly over another client and capture input meant for that other client. |
Beta Was this translation helpful? Give feedback.
-
I only skimmed over that protocol a few months ago and it seemed that it could be used outside of flatpak. But as said that might be a solution in the future, currently wlroots (and labwc) don't implement it anyway. Did you look into Qubes OS btw? They go a step further and use virtualization including USB controller mounting and things like that. I am not sure about the current wayland capabilities though, I think there is some development taking place for their nested compositors but I am not sure right now. |
Beta Was this translation helpful? Give feedback.
-
Yes. Also: whonix, kicksecure, and apparmor.d. |
Beta Was this translation helpful? Give feedback.
-
@Consolatis, |
Beta Was this translation helpful? Give feedback.
-
The data control protocol that I spoke about above (and that is getting used by wl_monitor.py) is an extension to the usual clipboard sharing behavior. That extension protocol should indeed be limited to privileged clients (however those would be defined). Usually how the clipboard works is that some application with keyboard focus says to labwc "here are some mimetypes that I would offer" and whenever a window gets focus it receives those offers from labwc. It can then request the content of one (or more) of those items by sending a fd over to labwc (usually just the write end of a newly created pipe) and the original application that offered the clipboard then gets send that fd and requested mime type and starts writing into the received fd. So what that means is that every application that gets (keyboard) focus can request the current "selection". Pressing I'll cook up a PR that disables user defined protocols. Not sure when though, but it shouldn't be that hard to implement. |
Beta Was this translation helpful? Give feedback.
-
Feel free to evaluate, config format not set in stone and up for discussion. |
Beta Was this translation helpful? Give feedback.
-
Yeah, I should probably add some nicer message if the protocols are not supported by the compositor.
Most of them can be found here: https://gitlab.freedesktop.org/wlroots/wlr-protocols (or here for the official ones).
This is basically the use-case for that aforementioned new security context protocol. It would allow to create a unix socket within the sandboxes and send the listen fd of those to labwc, attach a security context to them and labwc would then handle all the clients connecting there. And at the same time labwc could block all those protocols for those specific unix sockets but still allow them outside of the sandboxes. |
Beta Was this translation helpful? Give feedback.
-
thanks for this discussion! |
Beta Was this translation helpful? Give feedback.
-
@Consolatis I've also added one case with the multi-socket where I use the privileged socket selectively after desktop initialization: I'm using wlrctl's toplevel activate command to raise certain app windows (like email) instead of starting a second instance. And wlrctl toplevel needs the zwlr_foreign_toplevel_manager_v1 interface which is blocked in the unpriv socket. I am also using wayland-info to check the unpriv socket (and the standard socket after reconfigure-based blocking) for which interfaces remain unblocked. This all appears to be working nicely so far. Thanks very much for all of this help! I think I may add a clipboard manager next. |
Beta Was this translation helpful? Give feedback.
-
@Consolatis It seems like this multi-socket mechanism we're experimenting with now would be easily converted to, or implemented along with, one where the sandbox sockets were created externally. With the added benefit of providing some way to tailor which interfaces are allowed/blocked, which the security-context-v1 spec doesn't seem to include. Although, maybe the app or instance id (which the spec says is opaque to the compositor and only for use by the sandbox engine) in the security-context-v1 interface spec could tie the socket to a specific blockedProtocols section in the |
Beta Was this translation helpful? Give feedback.
-
What would be the expected behavior when removing one of the unprivileged sockets from the config (or renaming it) and doing a
In both cases the socket stops accepting new clients and is unlinked from the filesystem. |
Beta Was this translation helpful? Give feedback.
-
This is not about adding a feature that kills clients but rather the question of "what should happen on a What it is doing in my current implementation is:
So all currently connected clients to such a socket will keep working as usual until they disconnect. New clients will not be able to connect to that socket anymore though because we called
Currently that is not supported. I am not sure if we have / had an issue open for that or if that was about |
Beta Was this translation helpful? Give feedback.
-
As I mentioned here: Consolatis/wl_framework#1 (comment), I'm investigating https://github.com/talex5/wayland-proxy-virtwl. It supports 11 interfaces:
And the clipboard and primary selection are contained to the socket (no external selections pass into the sandbox, but selections made inside pass out). So this does what I wanted for most application sandboxes (but not sandboxes for desktop utilities like the taskbar), AND provides a secure clipboard. Maybe it might need more interfaces for more advanced apps - I haven't determined that yet. What does this imply vs. the multi-socket labwc? I'd use the multi-socket labwc to sandbox desktop utilities like the taskbar (sfwbar for me) and swaybg. And create a single unprivileged socket that has just enough to keep wayland-proxy-virtwl happy. But then I'd use a separate wayland-proxy-virtwl for each application sandbox that I want to secure against clipboard and primary selection spying. The labwc sockets (probably 3 or 4) would be long-lived - I wouldn't bother rewriting rc.xml to add/remove/change them for the lifetime of the session. The wayland-proxy-virtwl sockets would be temporary (sandbox lifetime). |
Beta Was this translation helpful? Give feedback.
-
Right. Blocking I tried that same trick with I can use blocking of Stealing the clipboard contents does mean that within-app menu-based paste won't work. I think that might cause problems in some apps, but am not sure. I was hoping that I wouldn't have to mess with within-app paste or even within sandbox cross-app paste of either primary or clipboard contents. This clipboard-stealing may still have a race condition. In theory, an app for which Or, I could try hacking wayland-proxy-virtwl to make it do what I want. I do like its |
Beta Was this translation helpful? Give feedback.
-
I did that, and it apparently works! All that I did was to disable wl_data_offers through the proxy. What this means is that clipboard, drag-n-drop and primary selection data never makes its way to the proxy's clients. Unfortunately, this does not allow data communication between different apps in the same sandbox (clients of the same proxy), but that case is rare because most of my sandboxes contain a single app. The next step is something to paste into the sandbox with an interactive confirmation, by using wl-paste and wl_virtual_keyboard.py. That will only work for text, but that's 99% of the cases I care about for pushing data into or between sandboxes. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Another security issue: currently, any application can steal focus by creating a new window. Is there any way in labwc to prevent the creation of a new window from stealing focus unless it is a child of the window currently focused, or unless something with access to the foreign_toplevel_management interface gives it focus? Considering that Wayland (without wayland_proxy_clipman) relies on focus to give clipboard offers in a "secure" way, not being able to somehow prevent a new window from always getting focused seems like a security hole. It's also important when using the virtual keyboard interface (or even the real keyboard, if one doesn't notice the focus change) . I have a very kludgy way to prevent this in my multi-sandbox with separate wayland_proxy_clipmans setup: I can send SIGSTOP to each wayland_proxy_clipman other than the one with a client I want to keep focused during a secure interaction (like typing a password), then after I'm done send them a SIGCONT. A stopped wayland_proxy_clipman effectively freezes all of its clients' ability to change window state. This is a lot easier than trying to enumerate the sandboxed processes themselves in order to send them all SIGSTOP. |
Beta Was this translation helpful? Give feedback.
-
My sandboxed labwc desktop, using wayland-proxy-clipname, is working well. And this has me thinking the following: I am not sure that "the compositor does everything" Wayland model needs to be the only way things can work. I think it is possible to off-load some Wayland protocol support to middleware. I think this would work for:
I think it would be possible, and maybe even easy, to implement a general-purpose Wayland middleware library (midway?) for the purpose of developing Wayland middleware. The typical piece of Wayland middleware would resemble wayland-proxy-... in that it would interface to the compositor on one side using the compositor's socket and the clients on the other by creating its own socket. What goes on in the middle can vary greatly, and could include things like network transparency (like waypipe) and remote desktop (wayvnc), as well as multiple clipboards (wayland-proxy-clipname), VM support (wayland-proxy-virtwl), middleman debuggers, etc. |
Beta Was this translation helpful? Give feedback.
-
I am using labwc, compiled without Xwayland support, as a desktop for multiple sandboxed applications. I think labwc without Xwayland is the only current adequate choice for this purpose. I applaud the labwc developers for filling this niche, and would very much like to see it sustained.
One very important part of my decision is reflected in this paragraph from labwc's motivation in the README.md:
The prospect of IPC as a method of sandbox escape is one thing I am trying to prevent. For example, I do not use a desktop session dbus with labwc. Rather, for apps that require dbus, I enclose a session dbus within the same sandbox as the app. Each dbus can only service clients in its sandbox.
However, all of these sandboxed apps use the same compositor. This is the reason for using labwc without Xwayland support. X11 is ruled out because all X11 clients have access to each other's interactions with the X11 server, including keyboard input and graphics output (I tried using Xephyr on X11 to mitigate this, but it is cumbersome to run every app in its own Xephyr window, and doing so slows down graphics). The same reason also rules out Xwayland.
That labwc of all Wayland projects remains the only viable option is seen when comparing the README.md quote above to this article:
https://blogs.kde.org/2020/10/11/linux-desktop-shell-ipc-wayland-vs-d-bus-and-lack-agreement-when-use-them
TL;DR: other Wayland compositors are considering (or already have) IPC-like communication between client peers in the style of dbus.
I think it would be great if labwc introduced more capability along the lines of security. For instance, security around cut and paste, to make it less likely that the user accidentally pastes to the wrong window. However, these are minor points relative to the importance of never supporting peer client IPC mechanisms.
Beta Was this translation helpful? Give feedback.
All reactions