Mikael Nordfeldth | 2 Jan 2009 00:21
Picon

Adding a "passthrough" mode for wrapping static files?

Hi,

I have recently experimented with suPHP and lighttpd (using Linux),
however I'm assuming this also affects apache. It works great for
everything PHP and I haven't tried other CGI scripts.

However, a friend pointed out to me that suPHP of course only wraps what
the webserver tells it to inside the proper uid:gid. lighttpd itself
doesn't care - thus making a symlink like this could compromise security
when accessing abc.com/cleartext.txt and reading the contents of the
otherwise protected secrets.php file:
  /srv/abc.com# ln -s ../123.com/secrets.php cleartext.txt

Files not passed through suPHP will be handled by the webserver - and
the webserver has access to non-script files in order to deliver static
files like images etc.

One solution I came to think of was to add a 'passthrough' mode (besides
'php' and 'execute') in suPHP and just run everything through it.
It would be simple and from what I can figure not very wasteful of
resources, considering there doesn't have to be any processing besides
getting a correct Content-Type headers and such.

In case this passthrough mode would be considered, which solution would
be best to determine uid:gid?
   a) get uid:gid from parent folder of static file
   b) still get uid:gid from the file itself (i.e. symlink, not target)

Any thoughts on this, or are there other solutions?
Also, it would be nice to know if this really also affects apache, or if
(Continue reading)

Scott | 6 Jan 2009 17:50
Picon

Symlink bug in 0.7.0

It seems there was either an unintended or undocumented change in
suPHP 0.7.0.  The following if() block is found on line 567 of
Application.cpp:

        if (directory.isSymlink()
            && !config.getAllowDirectoryOthersWriteable()
            && directory.hasOthersWriteBit()) {
            std::string error = "Directory \"" + directory.getPath()
                + "\" is writeable by others";
            logger.logWarning(error);
            throw SoftException(error, __FILE__, __LINE__);
        }

The way the first check is done regarding the symlink I'm not sure
that's the logic that's intended.  It also breaks allowing the
document root for a virtual host to be a symlink.  In 0.6.3, there is
a NOT before the "directory.isSymlink()" which is probably what it
should still be.  This correctly allows a document root to be a
symlink while still checking permissions elsewhere.  I believe the
correct code (at least what's in 0.6.3) is:

        if (!directory.isSymlink()
            && !config.getAllowDirectoryOthersWriteable()
            && directory.hasOthersWriteBit()) {
            std::string error = "Directory \"" + directory.getPath()
                + "\" is writeable by others";
            logger.logWarning(error);
            throw SoftException(error, __FILE__, __LINE__);
        }

(Continue reading)

Dave Kennard | 8 Jan 2009 20:33
Picon
Favicon
Gravatar

How to use chroot setting?

Hi

I want to set the user's folder as their root directory, so I have my suPHP settings like this:
;Path all scripts have to be in
docroot=${HOME}

;Path to chroot() to before executing script
chroot=${HOME}

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=false

But then when I load a php page I get the error "Internal Server Error - Could not execute script" (I have set suPHP to show errors in the browser).
If I comment out chroot or change it to / then it works okay.

suPHP is in paranoid mode, and I am setting SuPHP_UserGroup in the virtualhost configuration.

I just installed php5-cgi normally, I didn't compile it with the --enable-discard-path option, could this be the problem, or am I doing something else wrong?

Thanks

Dave

Are you a PC? Upload your PC story and show the world
_______________________________________________
suPHP mailing list
suPHP@...
http://lists.marsching.com/mailman/listinfo/suphp
Aki Tuomi | 9 Jan 2009 12:41
Picon

Re: How to use chroot setting?

On Thu, Jan 08, 2009 at 07:33:42PM +0000, Dave Kennard wrote:
> 
>    Hi
>    I want to set the user's folder as their root directory, so I have my
>    suPHP settings like this:
>    ;Path all scripts have to be in
>    docroot=${HOME}
>    ;Path to chroot() to before executing script
>    chroot=${HOME}
>    ;Check wheter script is within DOCUMENT_ROOT
>    check_vhost_docroot=false
>    But then when I load a php page I get the error "Internal Server Error
>    - Could not execute script" (I have set suPHP to show errors in the
>    browser).
>    If I comment out chroot or change it to / then it works okay.
>    suPHP is in paranoid mode, and I am setting SuPHP_UserGroup in the
>    virtualhost configuration.
>    I just installed php5-cgi normally, I didn't compile it with the
>    --enable-discard-path option, could this be the problem, or am I doing
>    something else wrong?
>    Thanks
>    Dave

Is your chroot set-up properly. PHP won't run in chroot if you don't
have all the libraries etc. it needs to perform. Check apache error log
and suphp log. 

Aki Tuomi
Dan Mahoney, System Admin | 9 Jan 2009 18:32

Re: How to use chroot setting?

On Fri, 9 Jan 2009, Aki Tuomi wrote:

> On Thu, Jan 08, 2009 at 07:33:42PM +0000, Dave Kennard wrote:
>>
>>    Hi
>>    I want to set the user's folder as their root directory, so I have my
>>    suPHP settings like this:
>>    ;Path all scripts have to be in
>>    docroot=${HOME}
>>    ;Path to chroot() to before executing script
>>    chroot=${HOME}
>>    ;Check wheter script is within DOCUMENT_ROOT
>>    check_vhost_docroot=false
>>    But then when I load a php page I get the error "Internal Server Error
>>    - Could not execute script" (I have set suPHP to show errors in the
>>    browser).
>>    If I comment out chroot or change it to / then it works okay.
>>    suPHP is in paranoid mode, and I am setting SuPHP_UserGroup in the
>>    virtualhost configuration.
>>    I just installed php5-cgi normally, I didn't compile it with the
>>    --enable-discard-path option, could this be the problem, or am I doing
>>    something else wrong?
>>    Thanks
>>    Dave
>
> Is your chroot set-up properly. PHP won't run in chroot if you don't
> have all the libraries etc. it needs to perform. Check apache error log
> and suphp log.

I vaugely wonder if it might make sense to statically compile your PHP 
binary for this.  Anyone here know how that would make things 
better/worse?

(it's a simple configure option to do so).

-Dan

--

-- 

"If you need web space, give him a hard drive.  If you need to do something really heavy, build him a computer."

-Ilzarion, late friday night

--------Dan Mahoney--------
Techie,  Sysadmin,  WebGeek
Gushi on efnet/undernet IRC
ICQ: 13735144   AIM: LarpGM
Site:  http://www.gushi.org
---------------------------
Grandy Fu | 16 Jan 2009 08:12
Picon
Favicon

suphp and environment variables

It seems that suphp has block all environment variables to be access by 
php-cgi.

I have compiled php with Oracle instant client. Oracle require an 
environment variable "TNS_ADMIN" to locate the configuration file. If I 
use mod_php, I have no problem connecting to oracle server. If I use 
suphp to call php-cgi, I have following error

"TNS:could not resolve the connect identifier specified"

those configurations are set in tnsnames.ora file indicated by TNS_ADMIN.

I have no problem using "php-cli" and "php-cgi" in console with 
TNS_ADMIN set.

My questions is that are there any way to pass some specific environment 
variable to php-cgi, say configure in suphp.conf?

Grandy
Micpoint BV | 23 Jan 2009 14:07

suPHP_ConfigPath ignored

Hi guys,

normally I'm not one to cry out for help. But I'm having an issue that's
driving me crazy. I've been searching the web and the suPHP list archives
for almost a week with no resolution. Staring at the config and log files
isn't helping either.
Sorry for the lengthy message. But I figure more info means less Q&A and
less of your time. Any help will be greatly appreciated.

A while back I installed a fresh Debian Lenny system with Apache2/PHP5 (CGI)
and suPHP on my EeePC. That system is working perfectly with user-specific
php.ini files. I documented the steps I needed to take to get it working the
way I want it to.

Then I created a new server (virtual with Xen 5) for hosting purposes. I
installed the same Debian Lenny with the same packages and configuration as
far as I'm aware of. suPHP works just fine, I see info messages in it's log
file when I open the test website in my browser. The custom .ini file I
saved to /etc/php5/conf.d/default.ini with general setting for all users is
applied as expected.
The problem is that the php.ini file in the directory specified with
suPHP_ConfigPath is completely ignored... When I check with "ls -alu" the
file access time doesn't change when I open the test website.

I've tried to copy the user-specific php.ini file to /tmp, give it 777
permissions and change suPHP_ConfigPath accordingly. I tried changing
ownership of this php.ini to the user running the PHP script. Also tried to
set suPHP_ConfigPath in different Apache config files. But nothing seems to
matter.

I know /etc/apache2/mods-available/suphp.conf is used since turning off the
suPHP_Engine there results in the browser downloading PHP files as plain
tekst with source code. I know I have the correct VirtualHost, the files are
served from that directory. Changing suPHP_ConfigPath to xxxsuPHP_ConfigPath
will prevent Apache from starting up as expected, so the suPHP_ConfigPath
property *is* recognized by Apache.

The only difference in installation between the two computers is that the
EeePC had libapache2-mod-php5 and php5 installed first, which I removed with
"dpkg --purge" before installing suPHP.

Packages:
apache2-mpm-prefork   2.2.9-10+lenny1
libapache2-mod-suphp  0.6.2-3
php5-common           5.2.6.dfsg.1-0.1~lenny1
php5-cgi              5.2.6.dfsg.1-0.1~lenny1

test.php:

<?php
   echo TESTZZZ;
   echo exec('cat /etc/passwd');
   var_dump(ini_get('upload_tmp_dir'));
?>

Returns:

Notice: Use of undefined constant TESTZZZ - assumed 'TESTZZZ' in
/home/zzz.zzz/web/abc/down.php on line 2
TESTZZZ
Warning: exec() has been disabled for security reasons in
/home/zzz.zzz/web/abc/down.php on line 3
bool(false)

/etc/apache2/mods-available/suphp.conf:

<IfModule mod_suphp.c>
   AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
   suPHP_AddHandler application/x-httpd-php
   <Directory />
      suPHP_Engine on
   </Directory>
   # By default, disable suPHP for debian packaged web applications as files
   # are owned by root and cannot be executed by suPHP because of min_uid.
   <Directory /usr/share>
      suPHP_Engine off
   </Directory>
# # Use a specific php config file (a dir which contains a php.ini file)
   suPHP_ConfigPath /home/000-suphp/zzz.zzz/web
# # Tells mod_suphp NOT to handle requests with the type <mime-type>.
#   suPHP_RemoveHandler <mime-type>
</IfModule>

/etc/apache2/sites-available/zzz.zzz:

<VirtualHost 192.168.3.84>
   ServerName zzz.zzz
   ServerAlias www.zzz.zzz
   DocumentRoot /home/zzz.zzz/web/
   TransferLog /home/zzz.zzz/logs/web.log
   suPHP_ConfigPath /home/000-suphp/zzz.zzz/web
</VirtualHost>
<VirtualHost 192.168.3.84>
   ServerName beta.zzz.zzz
   DocumentRoot /home/zzz.zzz/beta/
   TransferLog /home/zzz.zzz/logs/beta.log
   suPHP_ConfigPath /home/000-suphp/zzz.zzz/beta
</VirtualHost>

/etc/suphp/suphp.conf:

[global]
;Path to logfile
logfile=/var/log/suphp/suphp.log
;Loglevel
loglevel=info
;User Apache is running as
webserver_user=www-data
;Path all scripts have to be in
docroot=/home
;Path to chroot() to before executing script
;chroot=/mychroot
; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false
;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true
;Send minor error messages to browser
errors_to_browser=false
;PATH environment variable
env_path=/bin:/usr/bin
;Umask to set, specify in octal notation
umask=0077
; Minimum UID
min_uid=100
; Minimum GID
min_gid=33
[handlers]
;Handler for php-scripts
application/x-httpd-php=php:/usr/bin/php-cgi
;Handler for CGI-scripts
x-suphp-cgi=execute:!self

/etc/php5/conf.d/default.ini:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Default customized settings ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Prevent usage of unsecure functions
disable_functions =
dl,set_time_limit,exec,shell_exec,system,passthru,popen,pclose,proc_open,pro
c_close,proc_get_status,proc_terminate,proc_nice,posix_kill,posix_mkfifo,pos
ix_setpgid,posix_setsid,posix_setuid,diskfreespace,disk_free_space,disk_tota
l_space
; Allow users to upload bigger files
upload_max_filesize = 10M
; Don't set old (and deprecated) $HTTP_*_VARS for better performance
register_long_arrays = Off
; Set output buffer for better performance
output_buffering = 4096
; Disable $argc and $argv which aren't used by cgi
register_argc_argv = Off
; Don't automatically add slashes to all input data, instead use
addslashes() for data you are saving to a database
magic_quotes_gpc = Off
; Don't hash variables into $_ENV, use getenv() instead
variables_order = "GPCS"
; Log all errors for more stable, predicatable and secure code
error_reporting = E_ALL
; Cleaner code
allow_call_time_pass_reference = Off
; Don't allow <? ?> style tags for better portability
short_open_tag = Off

/home/000-suphp/zzz.zzz/web/php.ini

; Lock users in their own home directory
open_basedir = /home/zzz.zzz/
doc_root = /home/zzz.zzz/web/
; Temporary files
upload_tmp_dir = /home/zzz.zzz/tmp
session.save_path = /home/zzz.zzz/tmp
; Disable $argc and $argv which aren't used by cgi
register_argc_argv = Off
; prevent displaying errors in the client browser
display_errors = Off
log_errors = On
error_log = /home/zzz.zzz/logs/php.log
pmenier | 23 Jan 2009 14:30

Re: suPHP_ConfigPath ignored

Micpoint BV a écrit :
> Hi guys,
> 
> 
> normally I'm not one to cry out for help. But I'm having an issue that's
> driving me crazy. I've been searching the web and the suPHP list archives
> for almost a week with no resolution. Staring at the config and log files
> isn't helping either.
> Sorry for the lengthy message. But I figure more info means less Q&A and
> less of your time. Any help will be greatly appreciated.
> 
> A while back I installed a fresh Debian Lenny system with Apache2/PHP5 (CGI)
> and suPHP on my EeePC. That system is working perfectly with user-specific
> php.ini files. I documented the steps I needed to take to get it working the
> way I want it to.
> 
> Then I created a new server (virtual with Xen 5) for hosting purposes. I
> installed the same Debian Lenny with the same packages and configuration as
> far as I'm aware of. suPHP works just fine, I see info messages in it's log
> file when I open the test website in my browser. The custom .ini file I
> saved to /etc/php5/conf.d/default.ini with general setting for all users is
> applied as expected.
> The problem is that the php.ini file in the directory specified with
> suPHP_ConfigPath is completely ignored... When I check with "ls -alu" the
> file access time doesn't change when I open the test website.
> 
> I've tried to copy the user-specific php.ini file to /tmp, give it 777
> permissions and change suPHP_ConfigPath accordingly. I tried changing
> ownership of this php.ini to the user running the PHP script. Also tried to
> set suPHP_ConfigPath in different Apache config files. But nothing seems to
> matter.
> 
> I know /etc/apache2/mods-available/suphp.conf is used since turning off the
> suPHP_Engine there results in the browser downloading PHP files as plain
> tekst with source code. I know I have the correct VirtualHost, the files are
> served from that directory. Changing suPHP_ConfigPath to xxxsuPHP_ConfigPath
> will prevent Apache from starting up as expected, so the suPHP_ConfigPath
> property *is* recognized by Apache.
> 
> The only difference in installation between the two computers is that the
> EeePC had libapache2-mod-php5 and php5 installed first, which I removed with
> "dpkg --purge" before installing suPHP.
> 
> 
> 
> Packages:
> apache2-mpm-prefork   2.2.9-10+lenny1
> libapache2-mod-suphp  0.6.2-3
> php5-common           5.2.6.dfsg.1-0.1~lenny1
> php5-cgi              5.2.6.dfsg.1-0.1~lenny1
> 
> 
> 
> test.php:
> 
> <?php
>    echo TESTZZZ;
>    echo exec('cat /etc/passwd');
>    var_dump(ini_get('upload_tmp_dir'));
> ?>
> 
> Returns:
> 
> Notice: Use of undefined constant TESTZZZ - assumed 'TESTZZZ' in
> /home/zzz.zzz/web/abc/down.php on line 2
> TESTZZZ
> Warning: exec() has been disabled for security reasons in
> /home/zzz.zzz/web/abc/down.php on line 3
> bool(false)
> 
> 
> 
> /etc/apache2/mods-available/suphp.conf:
> 
> <IfModule mod_suphp.c>
>    AddType application/x-httpd-php .php .php3 .php4 .php5 .phtml
>    suPHP_AddHandler application/x-httpd-php
>    <Directory />
>       suPHP_Engine on
>    </Directory>
>    # By default, disable suPHP for debian packaged web applications as files
>    # are owned by root and cannot be executed by suPHP because of min_uid.
>    <Directory /usr/share>
>       suPHP_Engine off
>    </Directory>
> # # Use a specific php config file (a dir which contains a php.ini file)
>    suPHP_ConfigPath /home/000-suphp/zzz.zzz/web
> # # Tells mod_suphp NOT to handle requests with the type <mime-type>.
> #   suPHP_RemoveHandler <mime-type>
> </IfModule>
> 
> 
> 
> /etc/apache2/sites-available/zzz.zzz:
> 
> <VirtualHost 192.168.3.84>
>    ServerName zzz.zzz
>    ServerAlias www.zzz.zzz
>    DocumentRoot /home/zzz.zzz/web/
>    TransferLog /home/zzz.zzz/logs/web.log
>    suPHP_ConfigPath /home/000-suphp/zzz.zzz/web
> </VirtualHost>
> <VirtualHost 192.168.3.84>
>    ServerName beta.zzz.zzz
>    DocumentRoot /home/zzz.zzz/beta/
>    TransferLog /home/zzz.zzz/logs/beta.log
>    suPHP_ConfigPath /home/000-suphp/zzz.zzz/beta
> </VirtualHost>
> 
> 
> 
> /etc/suphp/suphp.conf:
> 
> [global]
> ;Path to logfile
> logfile=/var/log/suphp/suphp.log
> ;Loglevel
> loglevel=info
> ;User Apache is running as
> webserver_user=www-data
> ;Path all scripts have to be in
> docroot=/home
> ;Path to chroot() to before executing script
> ;chroot=/mychroot
> ; Security options
> allow_file_group_writeable=false
> allow_file_others_writeable=false
> allow_directory_group_writeable=false
> allow_directory_others_writeable=false
> ;Check wheter script is within DOCUMENT_ROOT
> check_vhost_docroot=true
> ;Send minor error messages to browser
> errors_to_browser=false
> ;PATH environment variable
> env_path=/bin:/usr/bin
> ;Umask to set, specify in octal notation
> umask=0077
> ; Minimum UID
> min_uid=100
> ; Minimum GID
> min_gid=33
> [handlers]
> ;Handler for php-scripts
> application/x-httpd-php=php:/usr/bin/php-cgi
> ;Handler for CGI-scripts
> x-suphp-cgi=execute:!self
> 
> 
> 
> /etc/php5/conf.d/default.ini:
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Default customized settings ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Prevent usage of unsecure functions
> disable_functions =
> dl,set_time_limit,exec,shell_exec,system,passthru,popen,pclose,proc_open,pro
> c_close,proc_get_status,proc_terminate,proc_nice,posix_kill,posix_mkfifo,pos
> ix_setpgid,posix_setsid,posix_setuid,diskfreespace,disk_free_space,disk_tota
> l_space
> ; Allow users to upload bigger files
> upload_max_filesize = 10M
> ; Don't set old (and deprecated) $HTTP_*_VARS for better performance
> register_long_arrays = Off
> ; Set output buffer for better performance
> output_buffering = 4096
> ; Disable $argc and $argv which aren't used by cgi
> register_argc_argv = Off
> ; Don't automatically add slashes to all input data, instead use
> addslashes() for data you are saving to a database
> magic_quotes_gpc = Off
> ; Don't hash variables into $_ENV, use getenv() instead
> variables_order = "GPCS"
> ; Log all errors for more stable, predicatable and secure code
> error_reporting = E_ALL
> ; Cleaner code
> allow_call_time_pass_reference = Off
> ; Don't allow <? ?> style tags for better portability
> short_open_tag = Off
> 
> 
> 
> /home/000-suphp/zzz.zzz/web/php.ini
> 
> ; Lock users in their own home directory
> open_basedir = /home/zzz.zzz/
> doc_root = /home/zzz.zzz/web/
> ; Temporary files
> upload_tmp_dir = /home/zzz.zzz/tmp
> session.save_path = /home/zzz.zzz/tmp
> ; Disable $argc and $argv which aren't used by cgi
> register_argc_argv = Off
> ; prevent displaying errors in the client browser
> display_errors = Off
> log_errors = On
> error_log = /home/zzz.zzz/logs/php.log
> 
> 
> 
> _______________________________________________
> suPHP mailing list
> suPHP@...
> http://lists.marsching.com/mailman/listinfo/suphp
> 
> 
> 
Hello

1) You didn't specify suPHP_UserGroup in your apache config ?

2) Since suphp-0.7.0 you must add quotes in these lines:

[handlers]
x-httpd-php="php:/usr/local/bin/php-cgi"
x-suphp-cgi="execute:!self"

Patrick
Micpoint BV | 23 Jan 2009 15:03

Re: suPHP_ConfigPath ignored

Hi Patrick,

thanks for your quick reply. I added the quotes to be sure.

The property suPHP_UserGroup isn't supported by my setup:

Starting web server: apache2Syntax error on line 8 of
/etc/apache2/sites-enabled/zzz.zzz:
Invalid command 'suPHP_UserGroup', perhaps misspelled or defined by a module
not included in the server configuration
 failed!

Won't it just run the PHP scripts as their respective owner?
Users can only use FTP to upload files which will always get the correct
owner. And when they use HTTP upload suPHP will make sure the uploaded files
have the same owner. At least to my knowledge.

Any idea as to why suPHP_ConfigPath would be ignored?

Cheers,
William

-----Original Message-----
From: pmenier [mailto:suphp@...] 
Sent: Friday, January 23, 2009 2:30 PM
To: suphp@...
Cc: suphp@...
Subject: Re: [suPHP] suPHP_ConfigPath ignored

Hello

1) You didn't specify suPHP_UserGroup in your apache config ?

2) Since suphp-0.7.0 you must add quotes in these lines:

[handlers]
x-httpd-php="php:/usr/local/bin/php-cgi"
x-suphp-cgi="execute:!self"

Patrick
Graeme Fowler | 23 Jan 2009 15:10

Re: suPHP_ConfigPath ignored

On Fri, 2009-01-23 at 15:03 +0100, Micpoint BV wrote:
> Any idea as to why suPHP_ConfigPath would be ignored?

Because, perhaps, you haven't loaded the suPHP Apache module?

The config you posted doesn't show the line:

LoadModule suphp_module modules/mod_suphp.so

...anywhere. That's not to say it isn't anywhere else, but you need to
load it *somewhere* or Apache won't know what to do.

Graeme

Gmane