Some background info

First a little background on what happens when you type a command into your shell, for example ls. If you had entered /bin/ls then the shell would have a path to the executable and it can run it straight away. Otherwise it needs to know what you mean by ls.

The shell first looks to see if what you have specified is a shell function, shell built-in, etc. If it is then the story ends there, if not the shell looks for the executable in your $PATH. $PATH is a environment variable that probably looks something like this

/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
This means first see if there's a /bin/ls, if so run it, if not try /sbin/ls and so on. Of course most shells usually use a hash table to remember where executables actually are, so that they only actually look at the actual contents of the directories as a last resort, as it would slow things down a lot.

The Scenario

Now that we have a basic background on the role $PATH plays on your un*x system, lets go through a hypothetical scenario that illustrates the dangers of placing . (the current directory) and ~/bin (the bin folder in your home directory) at the start of your $PATH.
Lets assume that somehow a malicious executable got into the current folder or into ~/bin. This could be via a security hole in your web browser or email client, because someone accessed your machine when you went to get a cup of coffee etc. You of course are blissfully ignorant. You then need to change some system config files, mount a filesystem, install some software or something else that require root priviliges.

bash-2.05a$ su
Password:
Without a care in the world you enter your root password. Congratulations, you've just given your root password away.
You might have done something like
sudo vi /etc/httpd/httpd.conf
Password:
Again you enter your password. Congratulations, a malicious program is running with superuser privs.

Oh my god! How did that happen ?

Lets look at what actually happened. You type 'su'. You didn't give a full path. Your shell looked for shell functions, built-ins etc. called su. It didn't find any. It then looked at your $PATH. And there in . was a file called su but which is actually an 'enhanced' version of it. It could just mail someone your root password, or run some destructive code. The second scenario is more or less identical, for a change lets suppose that ~/bin contained a file called vi which installs a trojan. You just ran it with superuser privs.

Well duh! Obviously if some guy has write access my files he can hose my system!

Not quite. With operating systems like DOS, Mac OS versions prior to Mac OS X, non NT-based versions of Windows etc. the system doesn't control access to files in the same way. You can access files whether they were created by you or are part of the system software. On a unix machine however, all files have permissions. If someone managed to install or run a dodgy executable on your system because of a flaky web browser then he can only do what you can do. Unless you surf the web as root (in which case you deserve to be struck down for using the name of root in vain) this means that he won't be able to overwrite system binaries or destroy other users' files. Anything in your home folder is at risk, but other stuff is safe.

This kind of risk is an escalation risk. It doesn't provide an entry point, but it can make existing ones worse. Of course losing all your personal files is bad, but it beats losing your system and all of your applications, having your machine turned into a warez server, spam relay etc. If the machine in question is a bigger server then dozens or hundreds of users' email or files could be at risk instead of just yours.

Of course there are quite a lot of ifs involved before this could actually happen. You are almost certainly a lot less vulnerable running pine and lynx than IE and Outlook Express. At the end of the day it's up to you decide whether the additional convenience is worth the slight risk. If you must put ~/bin and . in your path, at least put them right at the end, so if you are running a known executable the shell will always run the legitimate version. sudo (at least on my machine) deliberately checks the current directory last if it is in your $PATH (even if you put . elsewhere in your $PATH)

sources: the wise words of unix gurus
man page for bash
man page for sudo


As call pointed out, it's a bit paranoid to mark ~/bin as dangerous as if someone has access to ~/bin then they almost certainly have access to whatever configuration file your shell uses. I still feel that a bit of paranoia isn't necessarily a bad thing.
pfft suggests an interesting way of punishing nosy people with . in their $PATH, assuming that you are on a shared system (originally from a slashdot comment): put a shell script containing "rm ~/*" in your home directory, and call it ls.

Why putting ~/bin or . in your $PATH is not a bad idea:
  • Nobody, at least without a specific reason to, puts ~/bin (or .) at the beginning of their $PATH. They put it at the end. This means, the only way you can type 'su' and execute ~/bin/su is if su does not exist anywhere else in your path. In other words, all that is required for someone to gain your root password is for him to already have root access (so he can remove the su executable from your system). No added risk here.

  • If a cracker/etc. has access to ~/bin, they have access to ~/.bashrc, so they can add it to your path anyway. Of course, they still have to deal with point #1 above. Again, no added risk here.

  • Since said cracker has access to ~/.bashrc, he can add an alias to su (which will actually execute if you type it, even if there is an su in your $PATH). Here is the real risk. If he has access to your config files, he can alias whatever he wants to, and he doesn't need to bother with $PATH at all.

A note on "."

After an extended discussion with lj, I'm forced to concede that there is a situation in which having "." in your $PATH could be exploited by a malicious user. This involves (1) that the malicious user knows you have "." in your path, (2) that you are mucking around in that user's home directory, or /tmp, or somewhere else where that user has write permission, (3) that you mistype some common command (say you type "sl" instead of "ls," and (4) that the malicous user has guessed beforehand which command you would mistype and installed an executable in that directory named for that typo. If you did so, and he did so, he would be able to do anything your account has permission to do (including, if you're root, taking control of your system—unless, of course, you notice the typo or the executable file called "sl," in which case you'd repair your system, lock the account, and call the FBI...).

Is this scenario likely? No. I'd venture to say it's quite unlikely that it has happened, ever, in the history of computing. But it is possible.

Is this danger enough to offset the benefits of having "." in your $PATH? Well, I don't personally see the benefits of "." (I like the separation of commands, in my mind, from "current directory" scripts—configure, autoinstallers, etc.). As root, well, it's a good idea to keep your $PATH simple. "." has no place in it, or "~/bin" for that matter (if root wants to add a binary to his system, he can just put it in /usr/bin or /usr/local/bin. If he wants it only available to super users, he can add it to one of the "sbin" directories. "~/bin" is a workaround for those users who don't have write access to these directories). As a normal user, I'd say it's a toss-up. The likelihood of exploit is about at the level of a cracker guessing your random alphanumeric 8-character password. If you find "." useful, use it.

Log in or register to write something here or to contact authors.