php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #3076 system and popen are ok in safe_mode, not backquotes
Submitted: 1999-12-31 17:57 UTC Modified: 2002-05-24 20:33 UTC
From: djm at web dot us dot uu dot net Assigned:
Status: Not a bug Package: Program Execution
PHP Version: 4.0.3pl1 OS: all
Private report: No CVE-ID: None
 [1999-12-31 17:57 UTC] djm at web dot us dot uu dot net
Support for shell escapes is inconsistent in safe_mode.  Functions that use _Exec are ok, but backquotes are disallowed for no good reason I can see.  They don't seem to be any more dangerous than exec, system, or popen.
I have adapted the safe_mode_exec_dir code from _Exec to shell_exec.
I also made the detection of references to parent directories more accurate,
screening out false matches (e.g., it would disallow a program called "do...stuff").
I am curious why on Windows, _Exec uses binary mode but shell_exec uses text mode.  I didn't do anything about that, but it deserves at least a comment in the code.

--- ext/standard/exec.c 1999/12/30 22:31:15     1.1.1.2
+++ ext/standard/exec.c 1999/12/31 22:55:09
@@ -62,7 +62,7 @@
                overflow_limit = l;
                c = strchr(cmd, ' ');
                if (c) *c = '\0';
-               if (strstr(cmd, "..")) {
+               if (!strncmp(cmd, "../", 3) || strstr(cmd, "/../")) {
                        php_error(E_WARNING, "No '..' components allowed in path");
                        efree(buf);
                        return -1;
@@ -367,6 +367,7 @@
 {
        FILE *in;
        int readbytes,total_readbytes=0,allocated_space;
+       char *scmd;
        pval *cmd;
        PLS_FETCH();
 
@@ -374,18 +375,59 @@
                WRONG_PARAM_COUNT;
        }
        
-       if (PG(safe_mode)) {
-               php_error(E_WARNING,"Cannot execute using backquotes in safe mode");
-               RETURN_FALSE;
-       }
-
        convert_to_string(cmd);
+       scmd = cmd->value.str.val;
+
+       if (PG(safe_mode)) {
+               int l;
+               int overflow_limit, lcmd, ldir;
+               char *b, *c, *d=NULL, *tmp=NULL;
+
+               lcmd = strlen(scmd);
+               ldir = strlen(PG(safe_mode_exec_dir));
+               l = lcmd + ldir + 2;
+               overflow_limit = l;
+               c = strchr(scmd, ' ');
+               if (c) *c = '\0';
+               if (!strncmp(scmd, "../", 3) || strstr(scmd, "/../")) {
+                       php_error(E_WARNING, "No '..' components allowed in path");
+                       RETURN_FALSE;
+               }
+               d = emalloc(l);
+               strcpy(d, PG(safe_mode_exec_dir));
+               overflow_limit -= ldir;
+               b = strrchr(scmd, '/');
+               if (b) {
+                       strcat(d, b);
+                       overflow_limit -= strlen(b);
+               } else {
+                       strcat(d, "/");
+                       strcat(d, scmd);
+                       overflow_limit-=(strlen(scmd)+1);
+               }
+               if (c) {
+                       *c = ' ';
+                       strncat(d, c, overflow_limit);
+               }
+               tmp = _php3_escapeshellcmd(d);
+               efree(d);
+               d = tmp;
+#if WIN32|WINNT
+               in = popen(d, "rt");
+#else
+               in = popen(d, "r");
+#endif
+               if (!in)
+                       php_error(E_WARNING,"Unable to execute '%s'", d);
+               efree(d);
+       } else { /* not safe_mode */
 #if WIN32|WINNT
-       if ((in=popen(cmd->value.str.val,"rt"))==NULL) {
+               in = popen(scmd,"rt");
 #else
-       if ((in=popen(cmd->value.str.val,"r"))==NULL) {
+               in = popen(scmd,"r");
 #endif
-               php_error(E_WARNING,"Unable to execute '%s'",cmd->value.str.val);
+               if (!in)
+                       php_error(E_WARNING,"Unable to execute '%s'",scmd);
        }
        allocated_space = EXEC_INPUT_BUF;
        return_value->value.str.val = (char *) emalloc(allocated_space);

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-07-29 15:16 UTC] waldschrott@php.net
Please verify that it?s still happening using the latest version of PHP (release 4.0.1pl2 or CVS).

Patch in here.
 [2000-08-01 00:24 UTC] waldschrott@php.net
user feedback: still appearing
 [2000-10-18 19:23 UTC] djm at web dot us dot uu dot net
The affected code hasn't changed significantly in 4.0.3pl1, so this is still relevant.  I did just notice one bug in the first line of the diff I submitted: it lets "whatever/.." through (where "/.." is at the end of the string).
That would be a third case that should be checked, for correctness.
The rest of the patch still applies, except that popen is now V_POPEN.

 [2002-05-24 20:33 UTC] derick@php.net
Thank you for taking the time to report a problem with PHP.
Unfortunately your version of PHP is too old -- the problem
might already be fixed. Please download a new PHP
version from http://www.php.net/downloads.php

If you are able to reproduce the bug with one of the latest
versions of PHP, please change the PHP version on this bug report
to the version you tested and change the status back to "Open".
Again, thank you for your continued support of PHP.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 16:01:29 2024 UTC