Secure Programmer: Minimizing Privileges
By David A. Wheeler2005-05-27
Minimize privileges granted
Ensure that you only grant the privileges a program actually needs -- and no more. The primary way that UNIX processes get privileges are the user and groups they can run as. Normally, processes run as the user and groups of their user, but a "setuid" or "setgid" program picks up the privileges of the user or group that owns the program.
Sadly, there are still developers on UNIX-like systems that reflexively give programs "setuid root" privileges. These developers think that they've made things "easy" for themselves, because now they don't have to think hard about exactly what privileges their programs need. The problem is that, since these programs can do literally anything on most UNIX-like systems, any bugs can quickly become a security disaster.
Don't give all possible privileges just because you need one simple task done. Instead, give programs only the privileges they need. If you can, run them as setgid not setuid -- setgid gives fewer privileges. Create special users and groups (don't use root), and use those for what you need. Make sure your executables are owned by root and only writeable by root, so others can't change them. Set very restrictive file permissions -- don't let anyone read or write files unless absolutely necessary, and use those special users and groups. An example of all this might be the standard conventions for game "top ten" scores. Many programs are "setgid games" so that only the game programs can modify the "top ten" scores, and the files storing the scores are owned by the group games (and only writeable by that group). Even if an attacker broke into a game program, all he could do would be to change the score files. Game developers still need to write their programs to protect against malicious score files, however.
One useful tool -- that unfortunately is a little hard to use -- is the chroot() system call. This system call changes what the process views when it views the "root" of the filesystem. If you plan to use this -- and it can be useful -- be prepared to take time to use it well. The "new root" has to be carefully prepared, which is complicated because correct application depends on the specifics of the platform and of the application. You must be root to make the chroot() call, and you should quickly change to non-root (a root user can escape a chroot environment, so if it's to be effective, you need to drop that privilege). And chroot doesn't change the network access. This can be a useful system call, so it's sometimes necessary to consider it, but be prepared for effort.
One often-forgotten tool is to limit resources, both for storage and for processes. This can be especially useful for limiting denial-of-service attacks:
- For storage, you can set quotas (limits) for the amount of storage or the number of files, per user and per group, for every mounted filesystem. On GNU/Linux systems see quota(1), quotactl(2), and quotaon(8) for more about this, but although they're not quite everywhere, quota systems are included in most UNIX-like systems. On GNU/Linux and many other systems, you can set "hard" limits (never to exceed) and "soft" limits (which can be temporarily exceeded).
- For processes, you can set a number of limits such as the number of open files, number of processes, and so on. Such capabilities are actually part of standards (such as the Single UNIX Specification), so they've nearly ubiquitous on UNIX-like systems; for more information, see getrlimit(2), setrlimit(2), and getrusage(2), sysconf(3), and ulimit(1). Processes can never exceed the "current limit," but they can raise the current limits all the way up to the "upper limit." Unfortunately, there's a weird terminology problem here that can trip you up. The "current limit" is also called the "soft" limit, and the upper limit is also called the "hard" limit. Thus, you have the bizarre situation that processes can never exceed the soft (current) limit of the process limits -- while for quotas you can exceed the soft limits. I suggest using the terms "current limit" and "upper limit" for process limits (never using the terms "soft" and "hard") so there's no confusion.
Tutorial Pages:
» Taking the fangs out of bugs
» Basics of minimizing privileges
» Minimize privileged modules
» Minimize privileges granted
» Minimize privileges' time
» Newer mechanisms
» Conclusions
» Resources
First published by IBM DeveloperWorks
| Related Tutorials: » How to Install PHP 5 on Linux » How to Install Apache 2 on Linux » How to Install MySQL 5.0 on Linux » SMB Caching » Mound --Bind » Tar Wild Card Interpretation |
