You want to avoid common security problems in your scripting.
Validate all external input, including interactive input and that from configuration files and interactive use.
In particular, never eval input that you have not checked very thoroughly.
Use secure temporary files, ideally in secure temporary directories.
Make sure you are using trusted external executables.
In a way, this recipe barely scratches the surface of scripting and system security.
Yet it also covers the most common security problems you’ll find.
Data validation, or rather the lack of it, is a huge deal in computer security right now.
This is the problem that leads to buffer overflows, which are by far the most common class of exploit going around. bash doesn’t suffer from this issue in the same way that C does, but the concepts are the same.
In the bash world it’s more likely that unvalidated input will contain something like ; rm -rf / than a buffer overflow; however, neither is welcome. Validate your data!
Race conditions are another big issue, closely tied to the problem of an attacker gaining an ability to write over unexpected files.
A race condition exists when two or more separate events must occur in the correct order at the correct time without external interference.
They often result in providing an unprivileged user with read and/or write access to files they shouldn’t be able to access, which in turn can result in so-called privilege escalation, where an ordinary user can gain root access.
Insecure use of temporary files is a very common factor in this kind of attack.
Using secure temporary files, especially inside secure temporary directories, will eliminate this attack vector.
Another common attack vector is trojaned utilities. Like the Trojan horse, these appear to be one thing while they are in fact something else.
The canonical example here is the trojaned ls command that works just like the real ls command except when run by root.
In that case it creates a new user called r00t, with a default password known to the attacker and deletes itself.
Using a secure $PATH is about the best you can do from the scripting side.
From the systems side there are many tools such as Tripwire and AIDE to help you assure system integrity.