COMMAND

    PHP3

SYSTEMS AFFECTED

    Those using PHP3

PROBLEM

    Kristian Koehntopp found following.  PHP3 (http://www.php.net)  is
    a scripting  language used  in many  webhosting setups.   Often in
    hosting setups so called  "safe_mode" is enabled, which  restricts
    the user in many ways.  For example, in safe_mode you are supposed
    to be able to execute only programs from a safe_mode_exec_dir,  if
    one is  defined.   Within that  directory there  should be  only a
    restricted command set that is considered safe.

    When   safe_mode   is   enabled,   PHP3   is   supposed  to  apply
    EscapeShellCmd() to each  shell command to  prevent the user  from
    breaking out  of this  directory.   As it  turns out,  the popen()
    function does not do this in safe_mode.  Kristian was able to  set
    up a web  server with safe_mode  enabled and a  safe_mode_exec_dir
    containing only "ls".  He then wrote the following script:

        <?php
          $fp = popen("ls -l /opt/bin; /usr/bin/id", "r");
          echo "$fp<br>\n";
          while($line = fgets($fp, 1024)):
            printf("%s<br>\n", $line);
          endwhile;
          pclose($fp);
        
          phpinfo();
         ?>

    Which gave me the following output:

        1
        total 53
        -rwxr-xr-x 1 root root 52292 Jan 3 22:05 ls
        uid=30(wwwrun) gid=65534(nogroup) groups=65534(nogroup)

    and from the configuration values of phpinfo():

        safe_mode            0             1


SOLUTION

    The following patch against functions/file.c fixes the problem:

    Index: functions/file.c
    ===================================================================
    RCS file: /repository/php3/functions/file.c,v
    retrieving revision 1.229
    retrieving revision 1.230
    diff -u -r1.229 -r1.230
    --- functions/file.c    2000/01/01 04:31:15     1.229
    +++ functions/file.c    2000/01/03 21:31:31     1.230
    @@ -26,7 +26,7 @@
        | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
        +----------------------------------------------------------------------+
      */
    -/* $Id: file.c,v 1.229 2000/01/01 04:31:15 sas Exp $ */
    +/* $Id: file.c,v 1.230 2000/01/03 21:31:31 kk Exp $ */
     #include "php.h"
    
     #include <stdio.h>
    @@ -51,6 +51,7 @@
     #include "safe_mode.h"
     #include "php3_list.h"
     #include "php3_string.h"
    +#include "exec.h"
     #include "file.h"
     #if HAVE_PWD_H
     #if MSVC5
    @@ -575,7 +576,7 @@
            pval *arg1, *arg2;
            FILE *fp;
            int id;
    -       char *p;
    +       char *p, *tmp = NULL;
            char *b, buf[1024];
            TLS_VARS;
    
    @@ -600,7 +601,11 @@
                    } else {
                            snprintf(buf,sizeof(buf),"%s/%s",php3_ini.safe_mode_exec_dir,arg1->value.str.val);
                    }
    -               fp = popen(buf,p);
    +
    +               tmp = _php3_escapeshellcmd(buf);
    +               fp = popen(tmp,p);
    +               efree(tmp); /* temporary copy, no longer necessary */
    +
                    if (!fp) {
                            php3_error(E_WARNING,"popen(\"%s\",\"%s\") - %s",buf,p,strerror(errno));
                            RETURN_FALSE;

    As a web  hoster, you should  not rely on  safe_mode for security,
    but  use  the  CGI  version  of  PHP  in  a chroot()ed environment
    instead.