Hi! On Wed, Jul 25, 2001 at 11:53:30PM +0200, you wrote: > Besides, I realised that I can't pass a command line to the popen'ed > program. That's useless. Sorry? From popen()'s manpage: -- snip -- 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; interpretation, if any, is performed by the shell. The mode argument is a pointer to a null-terminated string which must be either `r' for reading or `w' for writing. -- snap -- So, calling popen("ls -lF", "r") will return a FILE pointer to a pipe connected with the command "ls -lF", thus reading from it will return a directory listing. This also is one of the dangerous features of popen() (and system() as well), as it will pass the command to sh -c. That means you must never use it to call popen() with (unfiltered) user supplied data (at least not in suid-binaries or other stuff where the user supplying the data is not the same as the user running the program, e.g. in CGIs). For example, a common mistake in CGIs using popen() to sendmail to send an email is doing the following: snprintf(buffer, sizeof(buffer), "/usr/lib/sendmail -oi %s", email); sendmail = popen(buffer, "w"); [...] If email contains unfiltered input the user can supply via a form field, one could enter "bogus@email.address; rm -rf /". This would lead to popen() calling sh -c /usr/lib/sendmail -oi bogus@email.address; rm -rf / and that will not start sendmail, but also remove all files in directories the httpd-user has write access to. That's because the ";" is a command separator for the shell. One method to prevent that for any command is to replace every ' in the user-supplied data with '\'' (note that you have to double the backslash when adding that to C code) and enclose the resulting string in '. This way, the above command would become sh -c /usr/lib/sendmail -oi 'bogus@email.address; rm -rf /' This isn't dangerous anymore, as the ; is now part of the third parameter to sendmail and thus is no longer special to the shell. And even if someone entered "bogus@email.address'; rm -rf /" the first step would neutralize the ', resulting in sh -c /usr/lib/sendmail -oi 'bogus@email.address'\''; rm -rf /' I know this is far beyond the scope of the original question, but it's important to know when using popen() nonetheless. Also don't forget that the same applies to system() as well, which internally uses sh -c, too! Ciao Thomas -- Thomas Binder (Gryf @ IRCNet) gryf@hrzpub.tu-darmstadt.de PGP-key available on request! Vote against SPAM: http://www.politik-digital.de/spam/
Attachment:
pgpekjBQ7B26m.pgp
Description: PGP signature