X-Git-Url: https://sipb.mit.edu/gitweb.cgi/wiki.git/blobdiff_plain/c4eec3730a1306b1ce1881d4d8976fad170630cd..926761928f3f6e79e4eab57bab34b61aa89242a5:/doc/safe-shell.mdwn diff --git a/doc/safe-shell.mdwn b/doc/safe-shell.mdwn index 7c9bbb3..e57eba1 100644 --- a/doc/safe-shell.mdwn +++ b/doc/safe-shell.mdwn @@ -54,8 +54,7 @@ Disable filename expansion (globbing) upon seeing `*`, `?`, etc.. If your script depends on globbing, you obviously shouldn't set this. Instead, you may find -`[shopt](http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html) --s failglob` useful, which causes globs that don't get expanded to cause +[`shopt -s failglob`](http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html) useful, which causes globs that don't get expanded to cause errors, rather than getting passed to the command with the `*` intact. ### [`set -o pipefail`](http://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html) @@ -102,6 +101,20 @@ manual](http://www.gnu.org/software/bash/manual/html_node/Special-Parameters.htm for details on the distinction between `$*`, `$@`, and `"$@"` — the first and second are rarely what you want in a safe shell script. +## Passing filenames or other positional arguments to commands + +If you get filenames from the user or from shell globbing, or any other kind of positional arguments, you should be aware that those could start with a "-". Even if you quote correctly, this may still act differently from what you intended. For example, consider a script that allows somebody to run commands as `nobody` (exposed over `remctl`, perhaps), consisting of just `sudo -u nobody "$@"`. The quoting is fine, but if a user passes `-u root reboot`, `sudo` will catch the second `-u` and run it as `root`. + +Fixing this depends on what command you're running. + +For many commands, however, `--` is accepted to indicate that any options are done, and future arguments should be parsed as positional parameters – even if they look like options. In the `sudo` example above, `sudo -u nobody -- "$@"` would avoid this attack (though obviously specifying in the `sudo` configuration that commands can only be run as `nobody` is also a good idea). + +Another approach is to prefix each filename with `./`, if the filenames are expected to be in the current directory. + +## Temporary files + +TODO: mumble `mktemp`? + ## Conclusion When possible, instead of writing a "safe" shell script, *use a higher-level