5 ms·
It is correct that PHP's mail() function will fork a shell: sendmail = popen(sendmail_cmd, "w"); Which calls /bin/sh to execute sendmail_cmd. However, two t
by skuhn 12y ago
It is correct that PHP's mail() function will fork a shell:
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).
- mverwijs 12y agoWell, this is the first time I'm glad /bin/sh on Ubuntu got switched to 'dash'! (Assuming that dash is safe....)
- skuhn 12y agoLikewise, it's been a thorn in my side up until now. And it is safe, POSIX sh does not support exported functions, that is a bash-ism.
- mhurron 12y ago> It is correct that PHP's mail() function will fork a shell: > 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 to@someplace.com 'message string'
- skuhn 12y agoI haven't tried it, but that is the relevant line from the PHP C source. sendmail_cmd is a variable, so you're right, it will be expanded to whatever. 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.
- nitrogen 12y agoWhich 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_2011-c https://gist.github.com/nitrogenlogic/1022231#file-popen3_20... [1] http://linux.die.net/man/7/environ http://linux.die.net/man/7/environ