With sudo, complex argument validation is best in cover scripts

February 16, 2020

Suppose, as a not entirely hypothetical case, that you want to allow some people to run 'zfs destroy' to delete only ZFS snapshots (since ZFS cannot delegate this through its own permission system). You can tell ZFS snapshots apart from other ZFS objects because ZFS snapshots all have '@' in their names. There are two approaches to enforcing this restriction on 'zfs destroy' arguments. The first is to write a suitable sudoers rule that carefully constraints the arguments to 'zfs destroy' (see Michael's comment on this entry for one attempt). The second is to write a cover script that takes the snapshot names, validates them itself, and runs 'zfs destroy' on the suitably validated results. My view is that you should generally use cover scripts to do complex argument validation for sudo'd commands, not sudoers.

The reason for this is pretty straightforward and boils down to whitelisting being better than blacklisting. A script is in the position to have minimal arguments and only allow through what it has carefully determined is safe. Using sudoers to only permit some arguments to an underlying general purpose command is usually in the position of trying to blacklist anything bad (sometimes explicitly and sometimes implicitly, as in Michael's match pattern that blocks a nominal snapshot name with a leading '-'). General purpose commands are usually not written so that their command line arguments are easy to filter and limit; instead they often have quite a lot of general arguments that can interact in complex ways. If you only want to have a limited subset of arguments accepted, creating a cover script that only accepts those arguments is the simple approach.

Cover scripts also have the additional advantage that they can simplify the underlying commands in ways that reduce the chance of errors and make it clearer what you're doing. This is related to the issue of command error distance, although in these cases often your sudo setup is intended to block the dangerous operation in the first place. Still, the principle of fixing low command error distances with cover scripts applies here.

(Of course the downside is that now people have to remember the script instead of the actual command. But if you're extending sudo permissions to people who would not normally use the command at all, you have to train them about it one way or another.)


Comments on this page:

I accidentally came to this same thing independently. I have cover scripts in /adm/bin and gave myself NOPASSWD access to the directory. This entire path is only root-writable, of course.

I have a couple of scripts there that run apt commands in a limited way; I can update the system or delete old (specified) kernel versions if at least two kernels are installed.

I really just wanted to bring the friction of installing updates down to a minimum, without giving a hypothetical attacker free-ranging access to the system if they managed to get access to the sysadmin user account.

Written on 16 February 2020.
« Unix's /usr split and standards (and practice)
The case of mysterious load average spikes on our Linux login server »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Feb 16 02:16:35 2020
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.