31

PHP applications have a reputation for higher than average security problems. What configuration techniques do you use for making sure the application is secure as possible?

I'm looking for ideas like:

I normally use Linux, but feel free to suggest Windows solutions too.

8 Answers 8

15
  1. Use the open_basedir directive to confine your PHP scripts to their home directory and eventual extra application directories. This is very efficient by itself.

  2. Use hardened php because that costs nothing and it can help.

  3. Use suPHP to have PHP scripts execute as the owner of the file (one user per website) and avoid using files with bad permissions such as 777... suPHP can also allow you to have on php.ini per website so that one site's stupid requirement don't destroy everything.

  4. Mod_security is a big plus but needs to be well used and configured.

3
  • Some bad sites actually need register_globals and fopen so that's why you use a php.ini per site with suPHP. One site can just go kamikaze and the others be (almost) perfectly safe. Jun 6, 2009 at 9:50
  • 4
    If they use register_globals and fopen, it suggests the quality is so bad you may want to reconsider using them :) Jun 6, 2009 at 14:57
  • If they're paying 150€/mo, you don't reconsider. Jun 7, 2009 at 9:34
3

In my experience, most vulnerabilities on a PHP-based web site are the result of poor (site) design, rather than flaws in PHP itself.

Some quick tips:

  • Universally filter input, escape output. Clarificaiton: filter doesn't mean escape, it means "if I find something fishy in this user input, cause the submission to fail and tell the user to reformat."
  • Rather than using escapeshellcmd(), simply don't allow any user input to be executed in the shell. That's dangerous and probably never actually necessary.
  • Don't call functions like phpinfo() on a production site (or if you do, see below*).
  • When designing a web application, always consider "is this a possible attack vector?" Say, SQL injection. If the answer is "yes," plug it immediately--don't say "ok, I'll add that later in development as a feature." Security is never a feature.
  • Never output raw errors to the user; this means setting php.ini's display_errors = Off, log_errors = On. Trap run-time errors and output something pretty. Take Twitter's whale as an example: it won't give the user debug-level information, it just says "woops, something broke, please refresh".

*You might also take a peek at a short post I wrote called "Securing phpinfo(), sort of" and be sure to read the comments http://egovsergo.com/2009/04/03/protecting-your-phpinfo/ It was a quick idea I had to (somewhat) protect phpinfo() if I somehow forgot to remove it on a production site.

In a more general way, some developers write wrappers for sensitive functions which check whether not the "production site" flag is set or not, and disables the sensitive function in production.

2
  • My question was more about how to protect your server against badly written PHP. :) I didn't mean that PHP itself was insecure, more that it attracts less experienced developers and the standard library requires them to remember to protect every call, rather than the library protecting all users. +1 as it's a very useful answer. Jun 7, 2009 at 22:04
  • I got that impression and replied accordingly :) Thanks for the comment! I can't get into it all here, obviously, but those are some big pits. If you have more specific questions, you can surely pose them on Stack Overflow and I and everyone else will contribute. (And for what it's worth, I'm a ZCE).
    – msanford
    Jun 8, 2009 at 3:44
3

Other parameters that should be altered to harden the PHP:

safe_mode = Off
register_globals = Off
expose_php = Off
allow_url_fopen = Off
allow_url_include = Off
log_errors = On
error_log = /var/log/phperror.log
display_errors = Off
enable_dl = Off
disable_functions="popen,exec,system,passthru,proc_open,shell_exec,show_source,phpinfo"

Store all PHP errors in file /var/log/phperror.log:

touch /var/log/phperror.log
chmod 666 /var/log/phperror.log
1

I've added the dotdeb repositories to my /etc/apt/sources.lst

deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all

As they patch php / apache / mysql much more frequently than Debian does.

1

Consider setting up open_basedir on a "per site" basis. open_basedir is a php.ini setting which will prevent your scripts from accessing files outside of a defined white list. If your server hosts several sites, it'll prevent one site from reading the database settings from another site. It'll also prevent a php script from accessing/modifying core system files. Open basedir is easy to set up, just add the line "php_admin_value open_basedir /my/list/of/folders:/as/a/colon/seperated/list" to each Apache vhost.

Also consider turning off the PHP script engine for all sites/folders which shouldn't contain PHP scripts (e.g. an uploaded images folder). Again, this is simple, add "php_admin_value engine off" to any Apache VirtualHosts not needing php. To disable PHP in a directory, put the same thing into a Directory tag.

Run file permissions as tight as possible, avoid write access to PHP scripts for the Apache user, this prevents a running script from modifying itself or other scripts on the same site/server. Avoid 777 permissions if at all possible, figure out the minimum permissions required to run the application and use those.

If you're hosting multiple sites, each with their own database, use a seperate MySQL/Postgres user for each, and set permissions on each user such that they only have access to the relevant databases. Again this will prevent a rogue script from tampering with another application's database.

Suosin, HardenedPHP, mod_security and the like are all valuable as well, but use them in addition to a tightly locked down configuration, not instead of.

0

Suhosin has a rather substantial performance cost, so the "costs nothing" comment is a bit off.

2
  • 2
    What good is a fast, hacked website? :) hardened-php.net/suhosin/benchmark.html suggests 8.85% slower on one benchmark. That may be acceptable for the security benefits it provides. This probably should have been a comment rather than an answer. Jun 6, 2009 at 16:13
  • Suhosin protects primarily against local attacks. So, if you share your server with people you don't trust, it may be worth the slowdown. If you have your own server, or your own vm slice, I don't see the point.
    – Tom
    Jun 7, 2009 at 1:10
0

Are you looking for some basic firewall/topology suggestions? I like the idea of using things like pound to prevent access directly to the PHP webserver from the unwashed internets. That way you can also segregate the webserver from other parts of your network as well.

1
  • No, I'm looking for ways to improve the security of the PHP runtime. Jun 6, 2009 at 20:45
0

Using Suhosin/mod_security/SuPHP certainly will turn your PHP server secure. Disabling certain functions like exec, passthru, system and escapeshellcmd will help a lot too.

1
  • 1
    Isn't escapeshellcmd() just used to escape string? It doesn't provide any way to exec a process. How could someone use it to cause a problem? Jun 7, 2009 at 6:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .