I think @VinDuv has written the most concise and correct explanation I've seen so far, which is quite a feat given how much poor/misinformation I've seen. I think most explainers assume RHEL or similar where /bin/sh
is bash. But for my own understanding, I'm trying to summarise the issue here.
- Bash executes code it receives through environment variables crafted in a certain way, upon initialisation
- Environment variables are inherited by child processes (and their children, and their grandchildren...)
- The CGI protocol passes through things such as cookies and the query string through environment variables
- If the CGI program happens to be run by bash, you're pretty much hosed
- If the CGI program happens to call bash (See point 5), you're pretty much hosed- Unless you clean the environment first. Except nobody does that.
- ssh logins might be dangerous, but only if the user is authorised
- ssh scrubs the environment but lets some variables through by default.
- Some server programs such as rsync and version-control systems use ssh to encrypt the data stream, which might allow for shell access if the ssh login calls bash
- I have no idea whether they do that. Those accounts are supposed to be set to
nologin
anyway. No bash that way.
- I have no idea whether they do that. Those accounts are supposed to be set to
- This issue is made 1000% worse if
/bin/sh
is bash (like it is in many if not most linux distros, but not e.g. Debian any more.)- Not in BSDs either. Probably not in any of the commercial Unices either.
- But OS X's
sh
is bash.
- The
system()
family of functions in most programming languages calls/bin/sh -c "your code here"
- Which might call bash. See point 4.
- But many programming languages have a version of
system()
that doesn't call the shell at all.- Such as Perl's
system(@list)
, as opposed tosystem($string)
- Try it yourself:
system('/bin/echo', '$SHELL'); system('/bin/echo $SHELL');
- Try it yourself:
- But nine out of ten people don't use
system()
this way and probably aren't even aware of its existence. Despite it being both faster and safer.
- Such as Perl's
Am I missing any vectors?