Apache Security - Ivan Ristic [35]
Placing an interpreter (of any kind) into a cgi-bin/ directory can be dangerous. If this directory is public, then anyone can invoke the interpreter directly and essentially ask it to process any file on disk as a script. This would result in an information leak or command execution vulnerability. Unfortunately, there is no other way since this is how Apache's Action execution mechanism works. However, a defense against this type of attack is built into PHP, and that's what the --enable-force-cgi-redirect switch we used to compile PHP is for. With this defense enabled, attempts to access the PHP interpreter directly will always fail. I recommend that you test the protection works by attempting to invoke the interpreter directly yourself. The configure script silently ignores unrecognized directives, so the system can be open to attack if you make a typing error when specifying the --enable-force-cgi-redirect option.
* * *
Tip
To ensure no one can exploit the PHP interpreter by calling it directly, create a separate folder, for example php-cgi-bin/, put only the interpreter there, and deny all access to it using Deny from all. Network access controls are not applied to internal redirections (which is how the Action directive works), so PHP will continue to work but all attack attempts will fail.
* * *
Choosing Modules
PHP has its own extension mechanism that breaks functionality into modules, and it equally applies when it is running as an Apache module or as a CGI. As was the case with Apache, some PHP modules are more dangerous than others. Looking at the configure script, it is not easy to tell which modules are loaded by default. The command line and CGI versions of PHP can be invoked with a -m switch to produce a list of compiled-in modules (the output in the example below is from PHP 5.0.2):
$ ./php -m
[PHP Modules]
ctype
iconv
pcre
posix
session
SPL
SQLite
standard
tokenizer
xml
[Zend Modules]
If you have PHP running as an Apache module, you must run the following simple script as a web page, which will provide a similar output:
$extension_list = get_loaded_extensions( );
foreach($extension_list as $id => $extension) {
echo($id . ". " . $extension . "\n");
}
?>
For the purpose of our discussion, the list of default modules in the PHP 4.x branch is practically identical. From a security point of view, only the posix module is of interest. According to the documentation (http://www.php.net/manual/en/ref.posix.php), it can be used to access sensitive information. I have seen PHP-based exploit scripts use POSIX calls for reconnaissance. To disable this module, use the --disable-posix switch when configuring PHP for compilation.
In your job as system administrator, you will likely receive requests from your users to add various PHP modules to the installation (a wealth of modules is one of PHP's strengths). You should evaluate the impact of a new PHP module every time you make a change to the configuration.
Configuration
Configuring PHP can be a time-consuming task since it offers a large number of configuration options. The distribution comes with a recommended configuration file php.ini-recommended, but I suggest that you just use this file as a starting point and create your own recommended configuration.
Disabling Undesirable Options
Working with PHP you will discover it is a powerful tool, often too powerful. It also has a history of loose default configuration options. Though the PHP core developers have paid more attention to security in recent years, PHP is still not as secure as it could be.
register_globals and allow_url_fopen
One PHP configuration option strikes fear into the hearts of system administrators everywhere, and it is called register_globals. This option is off by default as of PHP 4.2.0, but I am mentioning it here because:
It is dangerous.
You will sometimes be in a position