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
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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 12:01:31 2024 UTC