Having at this point done a lot of reading on shell scripts, and a little bit of writing them, I'd like to know more about how to make them secure enough for privileged tasks. The main book I have on shell languages (Classic Shell Scripting from O'Reilly) covers this a bit, but not really in much depth IMO.
At this point I know a bunch of tricks and general advice for securing shell scripts, e.g.
- Use #!/bin/sh - (or equivalent) to make it harder to pass shell options
- Set various environment variables (e.g. PATH, IFS, LD_PRELOAD) to sane values (or maybe just unset the whole environment?)
- Use absolute paths wherever possible
- Quote or otherwise delimit all user input
- Never run user input (e.g. with eval)
But this is stamp collecting, not security. Just following a bunch of rules will probably not provide reasonable protection when dealing with scripts that run privileged.
So, what should I watch out for in privileged scripts? What flaws can come back to bite me, even if I follow all the usual common-sense rules?
Moreover, should I even be thinking of using shell scripts for privileged functions?
It depends a lot on what your scripts are supposed to do. Write dedicated scripts for dedicated tasks - that eases up sanity testing the user input and options in the scripts.
Never allow execution of things like "less", "more", "vi" or anything else that is able to spawn a shell.
Regarding environment variables, read the sudo man pages, as by default they do get unset unless specified otherwhise.
When you are done, double check that no one but root can change the file.
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
You assume people are rational and influenced by evidence. You must not work with the public much. -- Trilby
How to Ask Questions the Smart Way
And if one of the major usecases is "user logs in via SSH, and executes a script via sudo" think about using SSH command restriction instead. That way users don't get a shell on the target system at all, they can just execute that one command remotely. We have many such cases.
You can use a script function to set-up a more secure environment that you call at the start of every admin script. This could be your main stamp album for stuff that can be moved there.
A few more stamps to add to the collection (be sure to read up on them before use):
1) reset the command hash
2) prevent core dumps
ulimit -H -c0
3) set the IFS
4) clear all aliases (see unalias -a)
Also you can remove the ALL from sudo and add explicit commands to the the sudoers file. There's a lot of fine tuning you can do in sudoers - inc. env variables as teekay said.
But I'm no expert so best to check all of the above.
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle