Date: Thu, 3 Aug 2023 12:08:05 +0200 From: Matthias GerstnerTo: oss-security@...ts.openwall.com Subject: Mozilla VPN: CVE-2023-4104: Privileged vpndaemon on Linux wrongly and incompletely implements Polkit authentication Hello list, an openSUSE community packager wanted to add the Mozilla VPN client [1] to openSUSE Tumbleweed, which required a review [2] by the SUSE security team, as it contains a privileged D-Bus service running as root and a Polkit policy. In the course of this review we noticed a broken and otherwise lacking Polkit authorization logic in the privileged `mozillavpn linuxdaemon` process. We publish this report today, because the maximum embargo period of 90 days we offer has been exceeded. Most of the issues mentioned in this report are currently not addressed by upstream, as is outlined in more detail below. Introduction ============ The Mozilla VPN client is a multi-platform VPN solution offered by Mozilla based on technologies like Wireguard. For this review we did not look in detail into the VPN protocol specifics and cryptography, but focused on the privileged operations performed by the Mozilla VPN client daemon on Linux. The findings in this report relate to the Mozilla VPN client version 2.14.1. Broken Polkit Authentication Check ================================== The code for the privileged component in Mozilla VPN on Linux is mostly found in mozillavpn-2.14.1/src/apps/vpn/platforms/linux. The D-Bus method callbacks are found in src/apps/vpn/platforms/linux/daemon/dbusservice.cpp. Mozilla VPN ships a Polkit policy with the following content: ``` Activate the Mozilla VPN Activate the Mozilla VPN no auth_admin ``` Of these two privileged actions, the Polkit authorization check is only performed in the `activate` D-Bus method, while no such check is present at all in the `deactivate` method. For the activate D-Bus method the Polkit check is implemented in `PolkitHelper::checkAuthorization()` in src/apps/vpn/platforms/linux/daemon/polkithelper.cpp line 58: ``` h.m_subject = polkit_unix_process_new_for_owner(getpid(), 0, -1); ``` The UNIX process Polkit subject is deprecated and shouldn't be used anymore for most cases, because it affected by race conditions by design. Instead the D-Bus sender subject should be used, which is based on the UNIX domain socket used by D-Bus, to obtain the credentials of the client via the Linux kernel. Even worse, the UNIX process Polkit subject is initialized here using `getpid()` as the process ID and `-1` for the user ID. The latter asks Polkit to determine the given PID's user ID by looking into /proc. In summary this asks Polkit to check whether the privileged Mozilla VPN D-Bus service _itself_ is authorized to perform the action. Since The Mozilla VPN D-Bus service runs as root, this will always be true. This can be verified from the command line using a minimal pseudo configuration like this: nobody$ gdbus call -y -d org.mozilla.vpn.dbus -o / Deactivate the Mozilla VPN Deactivate the Mozilla VPN no auth_admin
Show comments (9)