| Securing PHP -
11-23-2003, 09:12 PM
Hi,
This's not my article , i've found it in SecurityFocus area , hope it'll useful for network administrators
-----------------------------------------------------------------------------------
[b]
Securing PHP: Step-by-step
by Artur Maj
In my previous article ("Securing Apache: Step-by-Step") I described the method of securing the Apache web server against unauthorized access from the Internet. Thanks to the described method it was possible to achieve a high level of security, but only when static HTML pages were served. But how can one improve security when interaction with the user is necessary and the users' data must be saved into a local database?
This article shows the basic steps in securing PHP, one of the most popular scripting languages used to create dynamic web pages. In order to avoid repeating information covered in the previous article, only the main differences related to the process of securing Apache will be described.
Operating system
Like in the previous article, the target operating system is FreeBSD 4.7. However, the methods presented should also apply on most modern UNIX and UNIX-like systems. This article also assumes that a MySQL database is installed on the host, and is placed in the "/usr/local/mysql" directory.
Functionality
Generally, functionality will be very similar to the one described in the previous article. However, there are some changes:
The web server must handle the PHP scripting language
The PHP component must be able to read and write users' data in a locally installed MySQL database
Security assumptions
In case of security assumptions, the following have been added:
The PHP configuration should take advantage of built-in security mechanisms
PHP scripts must be executed in a chrooted environment
The Apache server must reject all requests (GET and POST), which contain HTML tags (possible Cross-Site-Scripting attack) or apostrophe/quotation marks (possible SQL Injection attack)
No PHP warning or error messages should be shown to the web application's regular users
It should be possible to store incoming GET and POST requests into a text file which will make it possible to use additional, host-based intruder detection system (HIDS), e.g. swatch.
Preparing the software
First of all, we have to download the source code of the latest version of Apache, PHP and the mod_security module. The module will be used to implement the protection against CSS and SQL injection attacks. Next, the downloaded software must be unpacked and the content of the archive must be placed in the home directory. The source code of mod_security should be placed into the Apache's "src/modules/extra" directory:
gzip -dc apache_1.3.27.tar.gz | tar xvf -
gzip -dc php-4.3.2.tar.gz | tar xvf -
gzip -dc mod_security_1.5.tar.gz | tar xvf -
cp mod_security_1.5/apache1/mod_security.c apache_1.3.27/src/modules/extra/
If any available security patches to the above software exist, they should be downloaded and applied as well.
Before we start compiling the software, we must also decide, which of three methods of PHP installation we'll choose:
as a web server's static module
as a web server's dynamic module
as a CGI interpreter
Each of above methods has its advantages and disadvantages. Compiling PHP as a static module will benefit from improved web server performance, but upgrading to a newer version of PHP later on will require recompilation of the whole web server. The second option, compiling as a dynamic module, hasn't got this disadvantage but the performance of the web server is decreased by approximately 5%. Additionally, one more module would be needed: mod_so. The third method is to install PHP as a CGI interpreter - in conjunction with Apache's suEXEC mechanism this is quite an interesting solution. Unfortunately, when not properly installed it can pose a serious security threat.
From a security and performance point of view, the best choice seems to be compilation as a static module. That's why the rest of this article is based on that method of installation.
Installing PHP
Generally, the installation process of Apache with PHP is very similar to the process of installing Apache without PHP, as described in the previous article. The only difference is the use of two additional modules: mod_php and mod_security.
As in the previous article, we will start by creating an account and group called "apache". Then we must prepare the Apache web server as follows:
cd apache_1.3.27
./configure
and compile the PHP module:
cd ../php-4.3.2
./configure --with-mysql=/usr/local/mysql --with-apache=../apache_1.3.27 --enable-safe-mode
make
su
make install
Next, we move to the directory with Apache source, and continue installation:
cd ../apache_1.3.27
./configure --prefix=/usr/local/apache --disable-module=all --server-uid=apache --server-gid=apache --enable-module=access --enable-module=log_config --enable-module=dir --enable-module=mime --enable-module=auth --activate-module=src/modules/extra/mod_security --enable-module=security --activate-module=src/modules/php4/libphp4.a
make
su
make install
chown -R root:sys /usr/local/apache
In the above "./configure" command, only those modules that are necessary to fulfill functionality and security assumptions are used. The choice of modules was discussed in details of the previous article. Now the next step is to return to the PHP directory and to copy the default PHP configuration file:
cd ../php-4.3.2
mkdir /usr/local/lib
chmod 755 /usr/local/lib
cp php.ini-recommended /usr/local/lib/php.ini
chown root:sys /usr/local/lib/php.ini
chmod 644 /usr/local/lib/php.ini
In order for the PHP scripts to be properly handled by the Apache web server, the following line should be added to /usr/local/apache/conf/httpd.conf:
AddType application/x-httpd-php .php
At this point we can try to run Apache and check if PHP can properly communicate with MySQL. We can achieve this by using the sample "test.php" script with the following content (the "user_name" and "password" values should be changed in accordance with installed database):
<html><body>
<?php
$link = mysql_connect("localhost", "user_name", "password")
or die;
print "Everything works OK!";
mysql_close($link);
?>
</body></html>
The above web page can be viewed by using any Internet browser. If PHP instructions are properly interpreted and a connection to MySQL is established, we can start securing the software. If not - we should analyze the Apache and MySQL log files and eliminate the cause of the problems.
Next >>> |