SuPHP
From Wikichris
suPHP allows PHP to run as the user and group that owns the file.
In wordpress for example it allows to upload files, update wordpress itself or its plugins.
But an ovious security issues can makes this Apache module really dangerous for your other websites. Here is how I installed it only for Wordpress.
Install on Debian 6 Squeeze
let's start by the usual apt-get install
apt-get install libapache2-mod-suphp
But now suPHP is Enabled globally for Apache, which is frightening. So let's start by disabling it. I commented all the lines in suphp.conf
vi mods-available/suphp.conf
<IfModule mod_suphp.c>
# AddType application/x-httpd-suphp .php .php3 .php4 .php5 .phtml
# suPHP_AddHandler application/x-httpd-suphp
# <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 /etc/php4/cgi/suphp/
# # Tells mod_suphp NOT to handle requests with the type <mime-type>.
# suPHP_RemoveHandler <mime-type>
</IfModule>
I had a problem with "application/x-httpd-suphp" since my browser just downloaded it instead of showing HTML. So I changed the declaration at the end of /etc/suphp/suphp.conf
vi /etc/suphp/suphp.conf
[handlers] ;Handler for php-scripts ;application/x-httpd-suphp="php:/usr/bin/php-cgi" application/x-httpd-php="php:/usr/bin/php-cgi"
My Websites Config
Now let's add into the Wordpress vhost Directory declaration:
vi /etc/apache2/sites-available/wordpress
#[...]
<Directory /home/websites/wordpress/>
#[...]
<IfModule mod_suphp.c>
php_admin_flag engine Off
AddType application/x-httpd-php .php .php3 .php4 .php5
suPHP_AddHandler application/x-httpd-php
suPHP_Engine on
suPHP_ConfigPath /home/websites/
</IfModule>
</Directory>
#[...]
And I create /home/websites/php.ini
allow_url_fopen = Off display_errors = On display_startup_errors = On log_errors = On error_reporting = E_ALL error_log = "/var/log/apache2/php_user_errors.log" expose_php = Off magic_quotes_sybase = Off register_globals = Off open_basedir = "/home:/tmp" short_open_tag = On session.save_path = "/tmp" ;disable_functions = "phpinfo, apache_child_terminate,apache_get_modules,apache_get_version,apache_getenv,apache_note,apache_setenv,curl_exec,curl_multi_exec,dir,disk_free_space,diskfreespace,dl,eval,exec,fsockopen,highlight_file,ini_alter,ini_restore,ini_set,openlog,parse_ini_file,passthru,pclose,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,readfile,set_time_limit,shell_exec,show_source,stream_socket_server,symlink,system,virtual"
The last line "disable_functions" is the list of the function you don't allow. I commented it for the following test. Don't forget to remove the ";" after the test.
run a file /home/websites/wordpress/suphp.php with the following content:
<?php system( "/usr/bin/id" ); ?>
Adjusting
any error log must be checked in your apache usual error.log. For example by default in /etc/suphp/suphp.conf the following 4 options will block your website if your files are writable by the group
; Security options allow_file_group_writeable=false allow_file_others_writeable=false allow_directory_group_writeable=false allow_directory_others_writeable=false
It was insufferable so I changed into
; Security options allow_file_group_writeable=true allow_file_others_writeable=false allow_directory_group_writeable=true allow_directory_others_writeable=false
I had to cancel any writable rights for "others" (my upload directory):
chmod -R o-w /home/websites/wordpress
and it is also forbidden to be owned by root
chown -R chris.chris /home/websites/wordpress