PATH, functions and security. Bash scripting best practices.
Hello all.
I've been using linux for a few years and really enjoy it. I'm a self learner. I have written and am using quite a few home made scripts for different purposes. I sometimes come across bash scripts where commands are called via there full paths only. For instance "ls" becomes : Code:
LS="/bin/ls" Further more, if this is really on issue, what about overriding commands with functions? For example, this is what I get on Debian Squeeze: Code:
user@sys:~$ cp --version Code:
user@sys:~$ /bin/ls --version I've never seen any recommendations on that matter. As I said my view is if a potential attacker can do this sort of thing, it's already too late. What do you think? Am I missing something ? |
Full paths aren't to protect against attacks, they're used to protect against users. :)
For example, if a user creates a script or alias for 'ls', but hard-codes an option or number of parameters, another script invoking the user's 'ls' may fail or return incorrect results. |
Well, I'm not going to comment on industry practices, but I know why I use fully-qualified paths.
1) When I'm going to run my script from cron or init.d. Since these won't be launched by my shell, I can't presume my path will be valid. If I code the fully-qualified path, I know the script will work. 2) When I want the script to run against the correct directories no matter where I happen to be in the tree. This would be for commands that aren't in my path by design, input or output files, etc. In other words, it's all about functionality. It has nothing to do with security. |
@macemoneta, ok I had not thought about aliases but I've just tested this on my system and PATH has precedence over user aliases.
@SL00b, PATH is defined /etc/crontab on my system, so this wouldn't be an issue. I realise one can also redefine the PATH variable at the beginning of a script. I recall reading a while ago (can't remember where/who/what) that certain sysadmins wouldn't set PATH in order to prevent command overrides at the command prompt and forcing the users to invoke programs/scripts only via full paths. I guess there is a certain school of thought there, but thinking about it I realised this sort of practice is ineffective anyways. |
Quote:
Code:
MAKE=make Code:
MAKE=gmake |
Some commands, using the same name, exist both as bash built-in commands, and standalone tools which usually reside in /usr/bin; "echo" is one example of this. One may prefer, for various reasons, *not* to use the bash built-in, in which case the absolute path name must be used in order to differentiate between the two.
Richard |
Note however that the standalone tool will execute much slower than the built-in. Be mindful when writing loops.
Code:
$ time for i in {1..5000} ; do /bin/echo > /dev/null ; done |
path to command to override other alias
Hi.
A common reason, in addition to the other ones given, to create a 'full path' in your script is sometimes a system administrator will have already redefined a command in a system .rc For instance, said person thinks that removing a file should always be confirmed, so in a system file redefines for you: Code:
$ alias rm='rm -i' Code:
btw, when I think certain commands should not be used, I make a new command name, such as Code:
$ alias rmi='rm -i' Enjoy. -doug |
Although all processes have an idea of PATH, the content may not be what you want eg cron deliberately sets a minimal or non-path, because it can be invoked by any user for any purpose, so the less 'assumptions' the better.
Note also that on some systems you may have multiple 'versions' of a cmd eg on Solaris there are binaries derived from Unix System V and some from the UCB (Berkely; see *BSD systems). cron is a basic tool on all *nix. As above, aliases come into play, as do symbolic links .... One thing I always do for prodn scripts is to specify the shebang line eg '#!/bin/bash' as otherwise it will be called via the default shell of whatever env it happens to be in... |
Quote:
|
KuimFieg & LQParsons,
Welcome to LQ. I hope your time here helps you as much as mine has helped me. In order to help us better help you, please put code, command line output, config files, etc. inside [CODE] tags, aka "Code:" blocks. In case your're not familiar with them, there are 2 ways to generate "Code:" tags:
The [CODE] tags will make your posts easier to read, & that will get you more, faster, better answers. -- Again, help us help you. BTW, You can edit your post(s) to do this retroactively. Please do so soon. Thank you, & for the 2nd time, welcome. |
Thanks for all the answers. I wasn't really aware of bash built-ins being faster.
Quote:
Code:
alias rm='rm -i' && echo -e '#!/bin/bash -x\nrm "$1"' > rm_test.sh && chmod 755 rm_test.sh && touch remove_me && ./rm_test.sh remove_me Quote:
Code:
user@sys:~# grep $(id -un) /etc/passwd |
Quote:
Code:
$ ssh pc15370 While I think about it: the shell will fork, the forked process will call execvp or alike. And indeed there inside they use the defined _PATH_BSHELL constant (defined in paths.h as /bin/sh). So it’s hardcoded in glibc. I leave it here, in case someone wonders about it too. |
Given that I work on various flavours of *nix, I just take the 'practical' definition ie the default is whatever you get if you DON'T explicitly define it yourself :)
Basically never 'assume' ... https://secure.wikimedia.org/wikiped...Don%27t_assume Also, others may have a hand in setting the env where your script ends up running. |
All times are GMT -5. The time now is 12:52 AM. |