Apache Security - Ivan Ristic [36]
Sooner or later, you will get a request from a user to turn it on. Do not do this.
I am sure it seemed like a great idea when people were not as aware of web security issues. This option, when enabled, automatically transforms request parameters directly into PHP global parameters. Suppose you had a URL with a name parameter:
http://www.apachesecurity.net/sayhello.php?name=Ivan
The PHP code to process the request could be this simple:
echo "Hello $name!"; ?>
With web programming being as easy as this, it is no wonder the popularity of PHP exploded. Unfortunately, this kind of functionality led to all sorts of unwanted side effects, which people discovered after writing tons of insecure code. Look at the following code fragment, placed on the top of an administration page:
if (isset($admin) = = false) {
die "This page is for the administrator only!";
}
?>
In theory, the software would set the $admin variable to true when it authenticates the user and figures out the user has administration privileges. In practice, appending ?admin=1 to the URL would cause PHP to create the $admin variable where one is absent. And it gets worse.
Another PHP option, allow_url_fopen, allows programmers to treat URLs as files. (This option is still on by default.) People often use data from a request to determine the name of a file to read, as in the following example of an application that expects a parameter to specify the name of the file to execute:
http://www.example.com/view.php?what=index.php
The application then uses the value of the parameter what directly in a call to the include() language construct:
include($what) ?>
As a result, an attacker can, by sending a path to any file on the system as parameter (for example /etc/passwd), read any file on the server. The include( ) puts the contents of the file into the resulting web page. So, what does this have to do with allow_url_fopen? Well, if this option is enabled and you supply a URL in the what parameter, PHP will read and execute arbitrary code from wherever on the Internet you tell it to!
Because of all this, we turn off these options in the php.ini file:
allow_url_fopen = Off
register_globals = Off
Dynamic module loading
I have mentioned that, like Apache, PHP uses modules to extend its functionality dynamically. Unlike Apache, PHP can load modules programmatically using the dl( ) function from a script. When a dynamic module is loaded, it integrates into PHP and runs with its full permissions. Someone could write a custom extension to get around the limitations we impose in the configuration. This type of attack has recently been described in a Phrack article: "Attacking Apache with builtin Modules in Multihomed Environments" by andi@void (http://www.phrack.org/phrack/62/p62-0x0a_Attacking_Apache_Modules.txt).
The attack described in the article uses a custom PHP extension to load malicious code into the Apache process and take over the web server. As you would expect, we want this functionality turned off. Modules can still be used but only when referenced from php.ini:
enable_dl = Off
Display of information about PHP
I mentioned in Chapter 2 that Apache allows modules to add their signatures to the signature of the web server, and told why that is undesirable. PHP will take advantage of this feature by default, making the PHP version appear in the Server response header. (This allows the PHP Group to publish the PHP usage statistics shown at http://www.php.net/usage.php.) Here is an example:
Server: Apache/1.3.31 (Unix) PHP/4.3.7
We turned this feature off on the Apache level, so you may think further action would be unnecessary. However, there is another way PHP makes its presence known: through special Easter egg URLs. The following URL will, on a site with PHP configured to make its presence known, show the PHP credits page:
http://www.example.com/index.php?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
There are three more