Whenever the topic of viruses comes up on any tech-oriented public forum, we are often told by clueless commenters that Linux doesn’t have viruses because it is secure by design. When pressed, such people will talk of privilege separation in Linux. Sure, Windows has privilege separation too, and it has filesystem ACLs enabled by default, which allows fine-grained control, but this privilege separation is in inferior to that in Linux since it was only introduced in 1993, whereas Unix-like operating systems have supported the concept since the 1970’s.
Such commenters may be proud of the fact that they run Ubuntu in its default configuration, which does not allow root logins, but rather uses gksudo to pop up a box requesting your password before any action is taken as root. They never start a root shell, instead they prefix every privileged shell command with “sudo”.
There are two problems with this:
- Linux has viruses.
- Privilege separation in desktop Linux is so easily broken that you may as well not bother.
Of course, Linux viruses are not viruses in the 1990 sense of the word, they are worms exploiting things like weak SSH passwords and web apps with arbitrary shell execution vulnerabilities. But the things on Windows that we call viruses these days are very similar. The reason Linux viruses target servers instead of desktops is because there are more servers than desktops, and servers are high-value because they can send larger volumes of spam.
On the second point, if you don’t believe me, try this little experiment. In your favourite Ubuntu desktop, open a terminal window, and run the following shell command:
while ! sudo -n true </dev/null >/dev/null 2>&1 ; do sleep 1; done ; sudo id </dev/null 2>&1 | cat
That will silently poll sudo until it is able to run a command without asking for a password. So while that is running, click System > Administration > Synaptic Package Manager (or any other command that runs as root), and type in your password when it prompts. The shell command will complete as soon as you hit OK.
It only logs to the syslog when it successfully runs the command as root, at which point you’re screwed anyway, since the command running as root could edit the logs.
You may have noticed that if you run sudo in one terminal window, you still need to enter your password again when you run it from another terminal window. This is because sudo stores a separate password timestamp for each pseudo-terminal. However, this mechanism is not any sort of secure, and you can easily trick sudo into thinking it is connected to any terminal to which the current user has read access. The redirections in the shell command above cause sudo to treat the terminal as “unknown”, which gives you access to the same password timestamp that is used for commands run from the desktop.
Alternatively, try this one:
gksu --description 'Update Manager' --print-pass
Convincing, yes? The point is that a malicious application that runs from your main user account can easily gain root access, either by waiting for you to do some regular sysadmin task like updating your system, or by tricking you into thinking that it is a valid system component which is asking for your password.
All that remains, then, is to find some way, by vulnerability or social engineering, to run malicious code as the main desktop user. That’s really not that far from the situation in Windows.
The most significant security difference between Linux and Windows is popularity. Anyone using a Linux desktop for security reasons would do well to switch to FreeBSD or BeOS the moment Linux desktops becomes popular enough for virus writers to start targeting them.
[Update 2011-04-26: using PolicyKit‘s pkexec instead of sudo to authenticate sysadmin actions would address my primary concern here. But it would have to be used exclusively. As soon as you give sudo your password, you’re toast. Let’s hope the distros start heading in that direction.]
Cool command-line demo. I had known it was pretty easy to do that sort of thing, but it’s a very good visual demonstration. Unix security works well to separate administrative from non-administrative users, but it does basically nothing to stop admin users from doing anything, or to stop malicious programs from hurting the user they run as. And those are the real concerns today, at least on the desktop.
Linux really isn’t more secure than Windows, you’re right. This is sad, because it could be much more secure. Security on Windows is seriously limited by the number of closed-source third-party programs that users will install, which will be written insecurely and which will not opt into new security features. If a Linux distro pushed for real security, and came up with easy-to-use fail-safe security primitives (not brittle like AppArmor or SELinux), it could patch all its most-used programs to use them. Like how some distros compile all code in their repos to use non-executable stack/heap and so on.
Sandboxing seems to be the way forward on security for standard desktop/web apps. I’m going to bet that Chrome is a lot more secure than Firefox or IE even if you neglect popularity. If you can rewrite most of your code so that it can’t affect the system other than by passing messages to much smaller trusted programs, you drastically reduce attack surface. Unfortunately, this generally requires a ton of effort for large programs, which are the ones that pose the most risk.
The most interesting OS on the security front seems to be Chrome OS. Have you read about its security model? All applications have approximately the privileges of web pages; everything is extensively sandboxed; and there’s a chain of trust by which read-only firmware validates read-write firmware which validates the kernel which validates every single block of the root filesystem against a table of hashes signed by Google. So even if you somehow manage to run arbitrary code (which user-installed applications can’t), and break through the sandboxes and leverage some vulnerability to gain root access, the user just has to reboot and they’re asked if they want to reimage the OS. Which, of course, also silently auto-updates.
This is very promising, because it’s based on an established security model that’s very suitable to today: nothing is trusted. Unix and Windows both have security models that assume you only need to protect users against each other, not against themselves, and that some users are trusted. This was reasonable in 1970 and 1990, but not now. The web doesn’t trust anything. As more and more capabilities are added to the web platform, it will compete with traditional programs more and more, and OSes like Chrome OS will become more and more feasible. Eventually, with things like NaCl, I don’t see why you’d ever have to run native apps.