Securing PHPHow to install PHP securely with Apache on a Linux server.
by Mike Peters, August 2004 Introduction PHP is a popular scripting language used to create dynamic websites on millions of servers worldwide. Serving dynamic pages means giving users access to commands, files and network connections on the server opening up many potential security risks. We can significantly reduce these risks by correctly configuring the server but it must be remembered that there is always a level of responsibility for the programmer to make sure his scripts are secure. In a previous article I looked at installing Apache in a chroot jail. This article first looks at the extra steps needed to add PHP to that setup and goes on to discuss how to run PHP securely on your server. Different Methods of Install. There are several different ways to install PHP on a server, either as a CGI interpreter or an Apache module. Each method has its own advantages and disadvantages making it more suitable to one situation over another. Installing PHP as a CGI interpreter offers the opportunity to have different PHP processess running as different user IDs under different virtual hosts, using Apache's suEXEC. However this method of installation may be slow and is fraught with risks if mis-configured. Alternatively, we can install PHP as an Apache module, which is the method we
will concentrate on in this article. When installing as an Apache module you have
a further choice, whether to compile as a static or dynamic Apache module. A static
module has the advantage of increased performance but when you wish to upgrade, you
have to recompile both PHP and Apache. With a dynamic module, you lose some
performance and you need to have your Apache compiled to suport dynamic modules
requiring the Compiling Apache and PHP. For a detailed description of installing Apache, refer to my earlier article, Securing Apache. In this article I will only look at the extra considerations needed to add PHP to that setup. When deploying PHP on your web server, one further consideration worth making, is to include mod_security in you Apache installation. This will provide you with an extra defence against Cross Site Scripting and SQL injection attacks. Static Module If you are compiling PHP as a static module you will need to compile it before Apache with ./configure --with-mysql=/usr/local/mysql --with-apache=/path/to/apache_source --enable-safe-mode
make
su
make install
Extract the mod_security source
and copy Now you can compile Apache as normal adding the options Dynamic Module To install PHP as a dynamic module, install Apache first and compile your PHP source with ./configure --with-mysql=/usr/local/mysql --with-apxs=/usr/sbin/apxs --enable-safe-mode
make
su
make install
To install mod_security as a
dynamic module, extract the sources and Whichever method we are using to install PHP, only enable the least amount
of options needed for your needs. Including more functionality means
increasing the risk of vulnerabilities. Additionally, especially in a
multiuser environment, it is strongly recommended you use the
Install in Chroot environment In order to Chroot your server, you should refer to my earlier article, Chrooting Apache. Here I will only outline the details needed to add PHP to that environment. If you compiled PHP and mod_security as dynamic modules you need to copy
the modules to your
cp /usr/libexec/apache/libphp4.so /chroot/httpd/usr/libexec/
cp /usr/libexec/apache/mod_security.so /chroot/httpd/usr/libexec/
You will also need libmysqlclient and some other nescessary libraries.
cp /usr/local/mysql/lib/mysql/libmysqlclient.so.12 /chroot/httpd/usr/lib/
cp /usr/lib/libm.so.2 /chroot/httpd/usr/lib/
cp /usr/lib/libz.so.2 /chroot/httpd/usr/lib/
If you have installed PHP with additional features enabled you may need
more libraries. Check with Now we need to make a /tmp directory in our /chroot:
mkdir /chroot/httpd/tmp
chown root.root /chroot/httpd/tmp
chmod 1777 /chroot/httpd/tmp
Finally copy the PHP configuration file:
cp /etc/apache/php.ini /chroot/httpd/etc/
Configure Apache to Handle PHP Add the following lines to httpd.conf to enable PHP.
LoadModule php4_module libexec/libphp4.so
AddModule mod_php4.c
AddType application/x-httpd-php .php
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .class
The AddType directives ensure that any files with the extensions .php, .php3, .inc and .class are processed as PHP scripts. Many programmers use *.class and *.inc to name external files included by their scripts. Without these directives these files would be displayed as plain text in the client's browser, potentially revealing passwords or other sensitive data. Another way of acheiving the same affect is to use the
<Files ~ "\.inc(.php)?$">
Order allow,deny
Deny from all
Satisfy All
</Files>
will deny access to all files ending in .inc or .inc.php meaning they could
only be accessed using If you don't want it to be immediately obvious that you are running PHP on your server you can
use a different extension for your scripts. Using Defending Against Injection Attacks With mod_security mod_security is an intrusion detection and prevention engine for web applications which operates as an Apache module. It is used to sniff GET and POST requests to the server, rejecting potentially malicious requests according to the current configuration. In order to enable the module we need to add the following lines to our httpd.conf file:
LoadModule security_module libexec/mod_security.so
AddModule mod_security.c
To configure the module to scan GET and POST requests we need to add:
<IfModule mod_security.c>
# Turn the filtering engine On or Off
SecFilterEngine On
# Make sure that URL encoding is valid
SecFilterCheckURLEncoding On
# Unicode encoding check
SecFilterCheckUnicodeEncoding On
# Only allow bytes from this range
SecFilterForceByteRange 0 255
# Only log suspicious requests
SecAuditEngine RelevantOnly
# The name of the audit log file
SecAuditLog logs/audit_log
# Debug level set to a minimum
SecFilterDebugLog logs/modsec_debug_log
SecFilterDebugLevel 0
# Should mod_security inspect POST payloads
SecFilterScanPOST On
# By default log and deny suspicious requests
# with HTTP status 500
SecFilterDefaultAction "deny,log,status:500"
</IfModule>
The comments in the code should be enough to explain what each directive does.
This is the most basic configuration possible but will provide the following
advantages: We want to use mod_security particularly to prevent SQL and Cross Site
Scripting (XSS) attacks. In order to do so we add the following lines within
the
SecFilter "\.\./"
SecFilter "<(.|\n)+>"
SecFilter "'"
SecFilter "\""
The first line will prevent attempted directory traversal attacks, which are
attempts to access files outside the directories containing the current web
site. The second detects It should be noted that this method means that any of these characters submitted through HTML forms will cause the request to be denied. Programmers will have to convert forbidden characters to their appropriate special tag, (ie >, <, " etc.) using Javascript before forms are submitted to the server. Less strict detection of XSS attacks can be achieved by using Safe Mode One of the major concerns of PHP security in a multi-user environment is that scripts are run under the user ID of the server. This not only means that PHP users have access to whatever resources the server has access to, but that all PHP scripts have access to one another as they all operate with the same UID. Architecturally this problem is best solved at the OS level, and, although various solutions exist there currently is no entirely satisfactory solution. In the absence of a satisfactory solution, the PHP developers introduced safe_mode. Safe mode ensures that any file which is being accessed by a script is owned
by the owner of the script itself. In order to enable Safe Mode PHP must first
be compiled with support enabled, as described above, and the line
There are a number of further options which can be set in Safe Mode the most important of which are:
Other PHP Configuration Options Asides from Safe Mode there are a number of other security related options which can be set in the php.ini configuration file.
Summary The very nature of running dynamic web pages on a server makes it a risky prospect. The methods discussed here will decrease the risk of a break in and reduce the potential damage caused by a breach. As always, it is important that you remain informed about new vulnerabilities when they arise and apply security related patches as they become available. Nor should you neglect the security of the underlying web server and Operating System. Finally, you should remember that a portion of the responsibility for the overall system security depends upon the web application itself. |
|
