While I prefer and stick to OpenBSD most often these days (and thus doas(1)): I still support sudo on Linux for work (as well as on OSX for my work workstation).
This is simply to make some notes of style-guide and some fun "Gotchas" that I've encountered along the way with sudo.
Contents
Gotchas
Shell-globbing
Case
Provided users with the ability to modify zone files on an antique DNS system (via sudo). They'll be editing files in /var/named/master and can ls, grep, vi, rcsdiff, co, & ci any files within that directory; however, their users cannot read into /var/named/master/ otherwise.
Failure
A user tried to do the following - in order to find any DNS/TXT record where the MAC address of a device was noted:
sudo /bin/grep '52:54:00' /var/named/master/*
Seems reasonable, right? This System Administrator has the permissions to run /bin/grep with any arguments on this machine. So why didn't this work? Instead, the user received the error:
grep: /var/named/master/*: No such file or directory
Diagnosis
What ends up being passed to sudo is:
COMMAND=/bin/grep 52:54:00 /var/named/master/*
Here, the shell-glob provided to this bash session in: "/var/named/master/*" was expanded at the user-level before the command is handed-to sudo. Shell globs are always evaluated first and this must be considered with sudo.
When command doesn't exist
Case
Provided a remote user the ability to run /usr/sbin/dmidecode with particular arguments.
Failure
User could not run that command with those arguments. Listing available-commands-on-host with "sudo -u user -l" showed the command as allowed.
Diagnosis
The command of /usr/sbin/dmidecode was indeed allowed to be run on these OpenBSD hosts by our _nrpe user; however, the command lives in /usr/local/sbin/dmidecode (which was also explicitly listed in the policy).
Since the other team's code was referencing only /usr/sbin/dmidecode (which does not exist) - the command was refused.
Final: I wish sudo used an error more akin to "command not present" or "no such file" rather than:
Jan 24 08:26:34 randommachine sudo: _nrpe : command not allowed ; TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/sbin/dmidecode -s bios-release-date
Of course, none of this would have mattered if they'd a) checked path in their code b) properly done a sudo -l /usr/sbin/dmidecode -s bios-release-date and verified its output (even if just with &&) before trying to run it with that path.
Negating Spaces in wildcards
Case
User wants to be able to run /usr/bin/yum install myproject-* where * is the ever-changing version/sub/path number
Failure
If user is provided with:
user host=(root) /usr/bin/yum install myproject-*
They would be able to call: "sudo -u root /usr/bin/yum install myproject-*" they would also be able to install non-approved software via: "sudo -u root /usr/bin/yum install myproject-1.21 nmap openssh-server", etc.
Diagnosis
Initial diagnosis points to removing the ability to use space in the glob. This appears to be able to be done by negating the character field with [!\ ] or [! ]. However, since more characters are needed, the * is still necessary, which would result in something like:
user host=(root) /usr/bin/yum install myproject-[! ]*
While that appears reasonable and would work for a true regular expression, in glob-form that still would allow the user to pass in "myproject-1.2 nmap", etc.
True Fix
In order to support the development cycle for this user, instead we allow their wildcard/glob match, but then specifically also deny the ability to call the same with a space anywhere in it:
user host=(root) /usr/bin/yum install myproject-*, ! /usr/bin/yum install myproject-*[ ]*
Dangerous Commands
Basic danger: cp
So it's well known that giving root-access to use "cp" is extremely dangerous with sudo, but to review, a quick example:
$ sudo -l
User may run the following commands on this host:
(root) /usr/local/bin/backupmodify.py
(root) /bin/cp
$ sudo cp /usr/local/etc/backupconfig.cfg /usr/local/etc/backupconfig.cfg.old
$ sudo cp /usr/local/etc/backupconfig.cfg.new /usr/local/etc/backupconfig.cfg
While we may all agree this is not preferred, likely you can recognize that things similar to this exist in many machines. Now for the problem:
$ sudo cp /usr/local/bin/backupmodify.py /tmp/.hidden
$ sudo cp /bin/bash /usr/local/bin/backupmodify.py
$ sudo /usr/local/bin/backupmodify.py
$ sudo cp /tmp/.hidden /usr/local/bin/backupmodify.py
...and privilege escalation!
Certainly the above was just possible because the user could also run backupmodify.py, right?
$ sudo -l
User may run the following commands on this host:
(root) /bin/cp
$ cat ~/my-custom-sudoers
myuser ALL=(root) NOPASSWD: ALL
$ sudo cp ~/my-custom-sudoers /etc/sudoers
...and privilege escalation!