Use of Javascript rules in polkit

polkit is a service used in Ubuntu that allows unprivileged processes to access system services. It is invoked when you do things like:

  • Change the system date/time.
  • Add/remove users from Settings.
  • Installing/removing software

When you do these a dialog often pops up for your password, though this is configurable by the system administrator.

In Debian and Ubuntu we are running polkit 105, which is almost 8 years old due to upstream switching the configuration backend from a PKLA (keyfile based) format to a more flexible JS format. This was done using the mozjs library which was not considered secure enough at the time to use in Ubuntu.

Example of a PKLA rule:

[Normal Staff Permissions]
Identity=unix-group:staff
Action=com.example.awesomeproduct.*
ResultAny=no
ResultInactive=no
ResultActive=yes

Example of a JS rule:

// Allow systemd-networkd to set timezone, get product UUID,
// and transient hostname
polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.hostname1.set-hostname" ||
         action.id == "org.freedesktop.hostname1.get-product-uuid" ||
         action.id == "org.freedesktop.timedate1.set-timezone") &&
        subject.user == "systemd-network") {
        return polkit.Result.YES;
    }
});

Obviously the JS rules are a lot more flexible.

I’m currently investigating if we can update to the latest version of polkit (116 at this time) as it is desirable to get back into sync with upstream.

If you are using polkit rules on a system you are running can you comment here if:

  • You are running polkit on Ubuntu and have found the current PKLA format too limiting.
  • You are running other distros using newer versions of polkit with the JS support. Please give your experience of it.
5 Likes

@robert.ancell: that’s long overdue. Good luck in tackling that thing. And thanks!

4 Likes

Hey there,

I am using PKLA rules and find them too limiting. The most limiting factor is that there is no whitelisting functionality.

You can white or blacklist too narrow or broad groups, as I stated in my post. I don’t know how I missed this one …

I need modern polkit for https://gitlab.com/mikhailnov/system-autoupdate/-/blob/master/usr/share/polkit-1/rules.d/90-system-autoupdate.rules to work properly in Ubuntu. Writing rules in javascript and using a javascript engines to parse them sounds strange but is probably mostly ok in security terms, I can’t imagine an exploit.

In my case, I need the ability restrict users’ access to libvirt (only allow domains prefixed with $USER-), similar to: https://github.com/fxkr/virt-access/blob/master/23-virt-access.rules
The PKLA rules are too inflexible for libvirt.

I have been trying to work out why the polkit rules for udisks, udisks2 and udiskie were not working, on headless machines, but the reference to the “old” version in the documentation was working. Now I understand!

I would like to be able to filter by which unit is being managed and which management action, underneath the too-wide blanket of manage-units or manage-unit-files even if there is no JavaScript engine. It should be possible to add some more features to the pkla format to at least support this common use case.

It’s unlikely that new features will be added to the old pkla format unless upstream decided to re-adopt it.

I asked about some months ago too to debian maintainer about, and that’s where things are more complicated as there are less fans of JS rules there, so I think we should coordinate there to avoid having to maintain polkit alone.

1 Like

Agreed, and the historical issue was that it’s been considered up until now undesirable to have a Javascript engine in the mix here. I know that people have thought about using something smaller than Spidermonkey such as Duktape. That might be a solution which could work for us, but it’d have to be discussed with the security team first.