Central to POSIX-like operating systems is the concept of permissions. Ordinary users are very limited in what files they can make changes to or even view. Programs run by users inherit the user's permissions.
In a properly configured system, the running user will have read-write access to very few files outside of their home directory, if at all. So what should be done when the need arises to change these files? For example, a new user needs to be added, system-wide settings must be changed, updates need to be done, or something even more trivial, like a printer being added or a reboot issued. Well, in this case there are two tools which are used: sudo and su.
In this article, I will discuss various security concerns around common but technically improper usage of sudo and su.
Let me get this out of the way: unless you somehow lock yourself out of root access, do not ever log in directly as root. This should go without saying. Anything run as the root user will have full, unrestricted access to the system. This means that a mistyped or malicious command or piece of code could potentially wipe your system clean and, in the case of systems with an improperly engineered BIOS and systemd, could even brick the machine. Because of how dangerous and stupid running as root is, many programs outright won't run like this.
su is the oldest solution to this problem, first appearing in 1971. Therefore I will focus on su first. su is fairly straight-forward: you can change to any user, including root, if you know their password. Therefore the user has to also have a password actually set for their account.
In a multi-user system, there's an obvious security risk with su: every user who needs access to the root account (or any account) needs the password to that account. Consider, for example, a server which multiple employees have access to. All of them need to know the password, and when one of them leaves it's probably best to reset the password for the root account and then tell everyone the new password. If somebody does something malicious or irresponsible with the root account, it can also be a challenge to figure out who exactly did it.
There is another, more obscure issue with su. I was alerted to this by the Debian maintainer for the util-linux package, the package which provides su. su by default inherits the environment variables and current working directory from the user who runs it. The intuitive way to think about su is that when you switch to another user, the shell would behave as if you logged in as that user. This is not the case. It runs commands as the user, but with your environment variables.
An obscure but potentially significant security risk is introduced here. Consider the path, which is a variable which tells the shell where binaries can be found. If a user has a different path variable set in, say, .bashrc or .profile, they could have a malicious binary added in their path without root access. If they then log in to root via su and run that command, it will run with root privileges. Additionally, bad environment variables can cause unexpected and potentially harmful effects when ran as root. su provides a way around this:
su -
or, alternatively: su -l
These commands cause su to login to a new session, resetting environment variables to what the user logged in as provides. Alternatively, sudo -i
can be used when logging in to another user and su can be disabled or removed entirely.
sudo is about 10 years older than su. It improves quite a bit on su. Essentially it repelicates the behavior of su -c
or even su's main functionality with the aforementioned sudo -i
but it has much more granular control than su and the ability to log what user has issued a command. A huge benefit of sudo over su is that if a user has permission to use sudo, they can authorize commands be run as root with their password. The root password doesn't have to be given to absolutely anyone. Unfortunately, many people are now using it in incorrect and lazy ways.
Given that Ubuntu is the most popular Linux distribution in the world for both server and desktop usage, one would expect it to be fairly sensible in terms of security. Many take the Ubuntu defaults for granted and simply don't notice the glaring issue with how they use sudo. By default, Ubuntu has no root account and simply gives unrestricted sudo access to the first user created. Furthermore, they don't even prompt for a user password for sudo usage. This means that anyone who has access to a user's account with sudo permissions (from a mistakenly uploaded private key or an ssh session which was left logged on) now has full, unrestricted root access without a password. Even a bad script that calls sudo can be run without confirmation. I don't mean to rag on Ubuntu. It's an excellent distribution in a lot of ways. But why Ubuntu developers found this security configuration sensible is beyond me.
The best way to use sudo on a single-user system (like a persona computer or hobby server) is to not use it at all. Everything sudo can do can be done by symlinking su to su -
and making use of su -c
in place of sudo. Of course, you can use sudo, but it's overkill and gets you in bad security habits.
For a multi-user system, I can't think of a situation where su is better than sudo. What's important is configuring sudo properly. Nobody besides the system administrator should have unrestricted sudo access, and sudo should always be password-protected. sudo has the ability to restrict certain tasks and commands to certain users and groups. For example, the sysadmin account can have full access whereas a group created for web developers can have permission to use sudo exclusively to edit apache files and restart the apache server. This is the correct usage of sudo.
To summarize: on a single-user system like a personal computer, su is sufficient but be sure to always use the -l flag. If you insist on using sudo, make sure it prompts for password. On a multi-user system, make use of sudo but be very careful to configure groups and permissions sensibly and securely.