Professional PHP Programming - The Importance of Security (
Page 3 of 9 )
This chapter will
show you how to increase the security of your web site, not just by writing safe
PHP scripts but also by configuring your webserver correctly.
Security is
an often-neglected part of web sites. This is probably caused by the fact that
security is not easily quantifiable and is often not very visible to visitors of
your web site. In contrast, a lack of security may be very visible and the
consequences can be disastrous. A defaced web site is not only very
embarrassing, but it can scare off customers. If you knew the web site of an
on-line store had been hacked, would you still trust them with your credit
card information?
Another problem with security is that it is very
broad in its scope and that you will need to keep up-to-date all the time. You
need to maintain security; it is not just something you add after finishing a
project.
Starting at the BeginningRunning a secure web site
starts with a secure server to run it on. Unfortunately, setting up a secure
server and keeping it secure requires intimate knowledge of the operating system
used. You will likely have to change obscure configuration files and install
extra security software. Below is a short list of some of the things you can do
to dramatically increase the security on your server. This list is by no means
complete and is only meant to help you start securing your server. You should
consult books and/or web sites specifically about computer and Internet
security. The web site of the Computer Emergency Response Team, better known as
CERT, can be found at www.cert.org. It is an especially good starting point for
finding more information about security.
Fixes and
upgradesBefore you can start securing your server you need to make sure
your operating system is up-to-date and all the necessary fixes have been
applied. The web site for your operating system will probably have a complete
list of recommended upgrades and fixes.
Hardening your
serverThe process of securing a server is often called hardening.
Hardening a server is an essential step towards building a secure server. What
hardening essentially boils down to is removing all unnecessary services from
your server. For instance, does your server really need to run FTP, email and
print services? If you don’t use a particular service, all it does is increase
the chance of your server being hacked or crashed. Since you are setting up a
webserver, try to move all other services to other machines. If you remotely
manage a UNIX machine, consider replacing the telnet service with a secure
alternative, such as SSH (
www.ssh.fi) or OpenSSH
(
www.openssh.org). Both programs are secure
replacements for rcp/rsh and alleviate the need for ftp and telnet. If you do
decide to keep using telnet, you could install TCP wrappers (
ftp://ftp.porcupine.org/pub/security/index.html)
to significantly increase security.
Keeping an eye on your
serverIt is essential that you regularly check your server’s log files.
After doing this a few times, you will get a good impression of the messages the
log file will contain when the system is running as it should. When you notice
any deviations, you’ll know something is wrong and you need to investigate
further.
Staying informedStaying informed is an essential part
of maintaining a secure server. For instance, you need to know when new fixes or
upgrades for your operating system are available. Regularly checking web sites
such as Security Focus (
www.security-focus.com) and Packet
Storm (
packetstorm.securify.com)
is a great way of staying informed. Don’t forget to check the web site for your
operating system though.
Securing your Web ServerKeeping your
web server up-to-date can be fairly easy. Most vendors have mailing lists to
keep you informed of new versions of your web server and the availability of
patches or fixes. If your web site uses Apache, check out the Apache Week web
site (
www.apacheweek.com) and subscribe
to their weekly newsletter. This web site also has a complete archive of back
issues. Check your vendor’s web site or contact them for more information.
Again, web sites such as CERT, Security Focus and Packet Storm are a great
source of information. Another web site that may come in handy is WebServer
Compare (
webservercompare.internet.com).
They have quite a lot of information about different web servers and will make
choosing a suitable web server a lot easier.
Securing your web server
consists of several different steps. Since this book mainly concentrates on the
Apache web server, I will use Apache as an example. Most principles are more or
less the same for other web server, so you will probably be able to apply them
to the web server you are using.
Below is a list of configuration
issues for Apache. More information on configuring Apache can be found in the
on-line documentation on the Apache web site (
www.apache.org) or in the Professional Apache
book by Peter Wainwright.
Permissions of the ServerRoot
DirectoriesThe ServerRoot (the directory where Apache is installed)
should not be owned by the user the web server runs as (usually www or
nobody). In addition, both normal users and the user the web server runs as
should be unable to change anything in the ServerRoot or the directories below
it. This way you can make sure that it is very hard, if not impossible, for
users to change the configuration of the web server. You may want to change the
permissions on the DocumentRoot so your users are able to change the files in it
but no more.
Make sure the user the web server runs as has permission to
write in the log directory though. If you don’t, you will not have any log
files.
Stopping Users from Overriding Server Wide SettingsYou
have probably put some thought into the settings for your web server, so you
will most likely want to prevent your users from circumventing your server wide
settings. With Apache, this can be done with the AllowOverride directive. You
can specify None to completely forbid your users from overriding settings or you
can list the settings they are allowed to override.
Protecting your
Server’s FilesYou should not allow the web server access to files
outside the DocumentRoot. This can be done with a Directory statement.
DocumentRoot /usr/local/apache/htdocs
# Do not allow access to files outside DocumentRoot
<Directory />
AllowOverride None
Options None
Order deny,allow
Deny from all
</Directory>
# Allow access to files in DocumentRoot
<Directory /usr/local/apache/htdocs>
AllowOverride None
Options Indexes FollowSymlinks
Order allow,deny
Allow from all
</Directory>
This tells the web server not to access any files outside the
DocumentRoot. One important thing to realize is that you now need to tell the
web server that it is permitted to access files in the DocumentRoot. This has
already been done in the default Apache configuration, so this should not be a
problem.
Giving Each User their Own Home PageYou can use the
UserDir directive to allow users to have their own home page. Using the UserDir
directive has the potential to allow people to read files from the home
directory of the root user (usually / or /root). You can make sure this cannot
happen by disabling the home page for the root user. This only works for Apache
1.3 and newer though.
UserDir disabled
UserDir enabled alice bob
UserDir public_html
<Directory "/home/*/public_html">
AllowOverride None
Options IncludesNOEXEC SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
This configuration first disables personal home pages for all
users and then enables users alice and bob to have their own home page. Apache
will look for these home pages in the public_html directory of their home
directory. Users are not allowed to override the server wide settings but are
allowed to use SSI (but not start programs from within SSIs). Symbolic links are
only followed if the user also owns the file or directory they point to. That
way, users cannot easily provide web access to files that shouldn’t be
accessible via the web (such as someone else’s home directory). Note that this
example assumes that the home directories for all users reside in /home. If this
is not the case, simply add an extra Directory block for each directory. For
instance, if some of your users have a home directory located in /staff, you
could simply add the text below to the configuration file.
<Directory "/staff/*/public_html">
AllowOverride None
Options IncludesEXEC SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
Apache’s default configuration allows users to put a home
page in public_html and does not disable root’s home page. You could disable the
root home page by adding the line below to the configuration file.
UserDir disabled root
Server Side Includes (SSI)Server side includes can
be configured in such a way that it enables users to run arbitrary programs.
Since you have little control over what programs they run, you may want to
disable this feature. Completely disabling SSI is probably not
necessary.
Apache has the IncludesNOEXEC option to allow SSI, but
disallow users to start programs (or CGIs) from them.
Disabling the
execution of programs from a SSI may not be possible in your situation. Apache’s
default configuration has the use of SSI disabled.
Permitting CGI
Execution Only from Certain DirectoriesIt is a good idea to disallow the
execution of CGI scripts in directories other than cgi or cgi-bin of the web
server. You can do this by adding a ScriptAlias line to httpd.conf for every
directory where the execution of CGI scripts should be allowed and by making
sure the handler for CGI scripts is either commented out or removed altogether.
#AddHandler cgi-script .cgi
ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
<Directory "/usr/local/apache/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
<Directory "/home/*/public_html/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
The first parameter to ScriptAlias specifies how the CGI
scripts will be made available via the web, while the second parameter specifies
where the scripts are located on the server. You should include a Directory for
each aliased directory. Among other things, this makes sure someone cannot get a
list of all CGI scripts on your server. Also, note that the AddHandler directive
has been commented out.
The second Directory directive enables users to
create their own CGI scripts. This is could be done more elegantly via a
ScriptAliasMatch directive, but this is a bit easier to use. Note that the
ExecCGI option is used. This is not needed if a ScriptAlias is
used.
Allowing users to create their own CGI scripts is inherently a
security risk, so you may not want to allow your users to create their own CGI
scripts.
Apache’s default configuration has the cgi-script handler
commented out and has ScriptAlias and Directory directives for /cgi-bin/.
Note that you can disable CGI execution while still allowing people to use
PHP scripts.
Placing the PHP Parser outside the Web
TreePlacing the PHP parser outside the web tree is a very sensible thing
to do. This makes it very difficult to abuse the PHP parser on your web server.
Specifically, you do not want the PHP parser in the cgi-bin directory or any
other directory that allows the execution of CGI programs. However, if you are
using an Action directive to parse your script, than this will not be possible.
For the Action directive to work the PHP parser most be placed in a directory
that allows CGI execution. Placing the PHP parser outside the web tree only
works when using PHP scripts as CGI programs.
If you want to use PHP
scripts as CGI programs (and be able to place the PHP parser outside the web
tree), you need to check a couple of things.
- All PHP scripts must reside in a directory that allows CGI execution.
- The scripts must be marked as executable (only on UNIX machines).
- The script must contain a special line at the top with the path of the PHP
parser.
You can make your PHP scripts executable with the following
command:
chmod +x test.php3
This marks the script named test.php3 in the current
directory as being executable. This is only necessary for webservers running a
UNIX variant.
Below is a small example of a PHP script that can be run as
a CGI program.
#!/usr/local/bin/php
echo "This is a small CGI program.”
The first line contains the name and the location of the
program (in this case PHP) that should be used to run this script. In the
example the PHP parser is located in the /usr/local/bin directory.
©1998
Wrox Press Limited, US and UK.