Because that's what it's being hyped as, or more correctly hyped as "OH MY GOD IT'S THE END OF EVERYTHING" when in reality it appears that if you're not running ssh with forcecommands or a webserver with CGI enabled, you don't care, just like if you didn't run a webserver with PHP enabled a PHP vulnerability wouldn't really be much of an issue to you.
But it needs something to expose bash to the outside world. Without mod_cgi (or the like) or sshd with a specific configuration, a vulnerable bash isn't going to be remotely exploitable.
sendmail = popen(sendmail_cmd, "w");
Which calls /bin/sh to execute sendmail_cmd. However, two things must also be true:1. /bin/sh is bash
2. PHP has set environment variables with user-provided data
#1 is often the case, but is much less common now than in the past.
#2 is not commonly the case, PHP does not even automatically create PHP variables from user-provided data anymore (because it is a terrible idea to put untrusted data into a trusted scope without sanitizing).
> sendmail = popen(sendmail_cmd, "w");
> Which calls /bin/sh to execute sendmail_cmd.
Are you sure? It looks like (at least by default) sendmail_cmd is a string constructed by putting sendmail_path (from php.ini) together with the various options passed to mail(). For most *NIX sendmail_path is going to be /usr/sbin/sendmail and so would execute /usr/sbin/sendmail -t -i [email protected] 'message string'
popen()'s man page says:
FILE *popen(const char *command, const char *type);
[..]
The command argument is a pointer to a null-terminated
string containing a shell command line. This command is
passed to /bin/sh using the -c flag
[..]
Which is where /bin/sh gets involved. PHP should be calling pipe/fork instead of popen IMO, I can't see the point in invoking a shell.Ideally there would be something like a popenve() to simplify the process of opening the pipe(s) and passing arguments and environment.
There are also various other variations on the popen() concept, like my own popen3() implementations in C[0] (note that I'm not the only person to write a popen3; Python, Ruby, and probably other languages have their own).
However, I mimicked the real popen(), and my implementation uses /bin/sh as well. It would be easy to make a version of popen3() that accepts argument and environment arrays, but it would still be insecure if the environment was set to the calling process's environ pointer[1], and/or the command to be executed was a /bin/bash script.
[0] https://gist.github.com/nitrogenlogic/1022231#file-popen3_20... [1] http://linux.die.net/man/7/environ
And it is safe, POSIX sh does not support exported functions, that is a bash-ism.
From what I can tell you are affected only if you use CGI or the like somewhere in your response chain. AFAIK most people use http reverse proxies, phpfm, wsgi and the like. They are all unaffected.
So CUPS printer servers at universities may be vulnerable. Dhclient may be vulnerable to malicious DHCP responses. Anything that calls out may be vulnerable (lots of mail libraries actually call /usr/bin/sendmail or the like; better hope they don't use system() or a bash /bin/sh to do it).
This is a big deal because there's a ton of stuff that uses environment variables that is and is not a web server, and very little time to track it all down before a black hat or oppressive regime gets there first.
Why does it need to be worse than something you might find in PHP? If it's a worm that's been found in the wild spreading by exploiting a remote execution vulnerability in bash and cgi, isn't that bad enough?