From: hao at hrz dot tu-chemnitz dot de Operating system: any PHP version: 5.2.9 PHP Bug Type: Program Execution Bug description: escapeshellcmd() considered harmful?
Description: ------------ Using escapeshellcmd() alone without any additional filtering is not safe at all. Special care has to be taken for parameter handling and the use of ' and ". I would strongly recommend to drop this function and/or discourage its use in the documentation. In 2000 there was a bug report #3519 about this. But there is still no warning whatsoever anywhere. Now to the details. I'll point out a few security risks in examples given in the documentation and the documentation comments. #1 <?php $e = escapeshellcmd($userinput); // here we don't care if $e has spaces system("echo $e"); ?> Here you can still pass parameters to echo. E.g. a $userinput of '-n blah' will not output what you expected. This might not be a big deal with echo, but it definitely is with other programs. #2 <?php $f = escapeshellcmd($filename); // and here we do, so we use quotes system("touch \"/tmp/$f\"; ls -l \"/tmp/$f\""); ?> Note that paired quotes are not escaped by escapeshellcmd(). So given a $filename like '" ".htaccess' will create more than one file, in any directory you want. With '" -R "/' you might even start a full recursive directory listing. #3 (from davidwhthomas) <?php $result = exec(escapeshellcmd("tar -xvvf /path/to/$uploadedfile -C /path/to/extract/to/")); ?> With this little exec it might be possible to put any file anywhere on the filesystem (restricted by user rights of course) by adding the '-P' parameter. A attack might work as follows: Upload two files 'up.tar' and 'up.tar -P' simultaneously where up.tar contains the file and path with a leading slash. Quoting the filename does not fix the problem, see #2. So whats the point in having escapeshellcmd(), when there is a escapeshellarg() function? Is there any legitimate use case for escapeshellcmd()? As i said before, I would strongly recommend to drop this function and/or discourage its use in the documentation. Additionally i would add ' --' in the documentation example for escapeshellarg(): <?php system('ls -- '.escapeshellarg($dir)); ?> instead of <?php system('ls '.escapeshellarg($dir)); ?> to give interested users a hint for possible security risks. -- Edit bug report at http://bugs.php.net/?id=47694&edit=1 -- Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=47694&r=trysnapshot52 Try a CVS snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=47694&r=trysnapshot53 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=47694&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=47694&r=fixedcvs Fixed in CVS and need be documented: http://bugs.php.net/fix.php?id=47694&r=needdocs Fixed in release: http://bugs.php.net/fix.php?id=47694&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=47694&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=47694&r=needscript Try newer version: http://bugs.php.net/fix.php?id=47694&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=47694&r=support Expected behavior: http://bugs.php.net/fix.php?id=47694&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=47694&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=47694&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=47694&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=47694&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=47694&r=dst IIS Stability: http://bugs.php.net/fix.php?id=47694&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=47694&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=47694&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=47694&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=47694&r=mysqlcfg