php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #47694 escapeshellcmd() considered harmful?
Submitted: 2009-03-17 16:57 UTC Modified: 2015-02-03 06:57 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: hao at hrz dot tu-chemnitz dot de Assigned: yohgaki (profile)
Status: Closed Package: Program Execution
PHP Version: 5.2.9 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hao at hrz dot tu-chemnitz dot de
New email:
PHP Version: OS:

 

 [2009-03-17 16:57 UTC] 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.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-08 20:34 UTC] jani@php.net
-Package: Feature/Change Request +Package: Program Execution
 [2015-02-03 06:57 UTC] yohgaki@php.net
-Status: Open +Status: Closed -Type: Feature/Change Request +Type: Documentation Problem -Assigned To: +Assigned To: yohgaki
 [2015-02-03 06:57 UTC] yohgaki@php.net
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
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC