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.