Req->Doc #47694 [Opn->Csd]: escapeshellcmd() considered harmful?
| From: | yohgaki@php.net | Date: | Tue, 03 Feb 2015 06:57:46 +0000 |
| Subject: | Req->Doc #47694 [Opn->Csd]: escapeshellcmd() considered harmful? | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-11915@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=47694&edit=1
ID: 47694
Updated by: yohgaki@php.net
Reported by: hao at hrz dot tu-chemnitz dot de
Summary: escapeshellcmd() considered harmful?
-Status: Open
+Status: Closed
-Type: Feature/Change Request
+Type: Documentation Problem
Package: Program Execution
Operating System: *
PHP Version: 5.2.9
-Assigned To:
+Assigned To: yohgaki
Block user comment: N
Private report: N
New Comment:
Yes, it is. escapeshellcmd() is only good for supporting programmers, not for _external_ inputs.
This should be documented clearly and it is now.
http://php.net/manual/en/function.escapeshellcmd.php
Previous Comments:
------------------------------------------------------------------------
[2009-03-17 16:57:22] hao at hrz dot tu-chemnitz dot de
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 this bug report at https://bugs.php.net/bug.php?id=47694&edit=1